From 3ace4a00150e1e5dab1cf9b2be20e8cfaaf42b8d Mon Sep 17 00:00:00 2001 From: Stefan Seefeld Date: Fri, 7 Oct 2016 20:15:54 -0400 Subject: [PATCH] Adjust NumPy code to work with new directory / namespace structure. --- .travis.yml | 13 +- SConstruct | 4 +- config/__init__.py | 15 +- config/numpy.py | 86 +++ config/tools/doc.py | 5 + config/tools/sphinx4scons.py | 592 ++++++++++++++++++ doc/SConscript | 3 + doc/numpy/_static/bpl.png | Bin 0 -> 21289 bytes doc/numpy/_templates/layout.html | 4 +- doc/numpy/conf.py | 14 +- doc/numpy/index.rst | 7 +- doc/numpy/reference/binary_ufunc.rst | 25 +- doc/numpy/reference/dtype.rst | 13 +- doc/numpy/reference/index.rst | 4 +- doc/numpy/reference/multi_iter.rst | 19 +- doc/numpy/reference/ndarray.rst | 60 +- doc/numpy/reference/unary_ufunc.rst | 23 +- doc/numpy/tutorial/dtype.rst | 4 +- doc/numpy/tutorial/fromdata.rst | 4 +- doc/numpy/tutorial/index.rst | 4 +- doc/numpy/tutorial/ndarray.rst | 4 +- doc/numpy/tutorial/simple.rst | 4 +- doc/numpy/tutorial/ufunc.rst | 4 +- doc/python.qbk | 1 + include/boost/python/numpy.hpp | 33 +- include/boost/python/numpy/dtype.hpp | 30 +- include/boost/python/numpy/internal.hpp | 20 +- .../boost/python/numpy/invoke_matching.hpp | 30 +- include/boost/python/numpy/matrix.hpp | 61 +- include/boost/python/numpy/ndarray.hpp | 65 +- .../python/numpy/numpy_object_mgr_traits.hpp | 13 +- include/boost/python/numpy/scalars.hpp | 32 +- include/boost/python/numpy/ufunc.hpp | 66 +- src/SConscript | 10 + src/numpy/dtype.cpp | 104 +-- src/numpy/matrix.cpp | 35 +- src/numpy/ndarray.cpp | 18 +- src/numpy/numpy.cpp | 29 +- src/numpy/scalars.cpp | 18 +- src/numpy/ufunc.cpp | 26 +- test/SConscript | 15 +- test/numpy/{dtype_mod.cpp => dtype.cpp} | 11 +- test/numpy/dtype.py | 24 +- test/numpy/{indexing_mod.cpp => indexing.cpp} | 11 +- test/numpy/indexing.py | 20 +- test/numpy/{ndarray_mod.cpp => ndarray.cpp} | 9 +- test/numpy/ndarray.py | 20 +- test/numpy/{shapes_mod.cpp => shapes.cpp} | 11 +- test/numpy/shapes.py | 4 +- .../{templates_mod.cpp => templates.cpp} | 23 +- test/numpy/templates.py | 8 +- test/numpy/{ufunc_mod.cpp => ufunc.cpp} | 15 +- test/numpy/ufunc.py | 12 +- 53 files changed, 1200 insertions(+), 485 deletions(-) create mode 100644 config/numpy.py create mode 100644 config/tools/sphinx4scons.py create mode 100644 doc/numpy/_static/bpl.png rename test/numpy/{dtype_mod.cpp => dtype.cpp} (87%) rename test/numpy/{indexing_mod.cpp => indexing.cpp} (77%) rename test/numpy/{ndarray_mod.cpp => ndarray.cpp} (88%) rename test/numpy/{shapes_mod.cpp => shapes.cpp} (59%) rename test/numpy/{templates_mod.cpp => templates.cpp} (73%) rename test/numpy/{ufunc_mod.cpp => ufunc.cpp} (71%) diff --git a/.travis.yml b/.travis.yml index 1af4c095..97a4fc8a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,9 +26,11 @@ matrix: - compiler: gcc env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++11 - compiler: clang - env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98 + # clang generates an 'illegal instruction' error in the NumPy check. + # Perhaps we need to upgrade clang to a newer version ? + env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98 OPTIONS=--no-numpy - compiler: clang - env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11 + env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11 OPTIONS=--no-numpy - env: PYTHON=python DOC=1 @@ -41,8 +43,10 @@ addons: - gcc-4.8 - g++-4.8 - clang - - python-dev python-pip + - python-numpy + - python-sphinx - python3-dev + - python3-numpy - libboost-all-dev - xsltproc - docbook-xsl @@ -58,7 +62,6 @@ before_install: # conflicting UCS2 and UCS4 unicode. Modify the PATH to skip the TravisCI python. # See https://github.com/travis-ci/travis-ci/issues/4948 for details. - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") - - sudo pip install future install: # Install our own version of Boost (the subset we need) as the system version is @@ -82,7 +85,7 @@ before_script: - scons --version script: -- scons config --python=$PYTHON --boost-include=$HOME/Boost +- scons config --python=$PYTHON --boost-include=$HOME/Boost $OPTIONS - if [ "$DOC" ]; then scons doc; else scons && scons test; fi after_success: diff --git a/SConstruct b/SConstruct index 24de13dd..3f3dbfd4 100644 --- a/SConstruct +++ b/SConstruct @@ -40,7 +40,7 @@ env_vars = {} if 'CXX' in os.environ: env_vars['CXX'] = os.environ['CXX'] if 'CXXFLAGS' in os.environ: env_vars['CXXFLAGS'] = os.environ['CXXFLAGS'].split() env = Environment(toolpath=['config/tools'], - tools=['default', 'libs', 'tests', 'doc'], + tools=['default', 'libs', 'tests', 'doc', 'sphinx4scons'], variables=vars, TARGET_ARCH=arch, **env_vars) @@ -68,7 +68,7 @@ config_log = '{}/config.log'.format(build_dir) SConsignFile('{}/.sconsign'.format(build_dir)) #env.Decider('MD5-timestamp') env.Decider('timestamp-newer') -checks = config.get_checks() +checks = config.get_checks(env) if 'config' in COMMAND_LINE_TARGETS: conf=env.Configure(custom_tests=checks, log_file=config_log, conf_dir=build_dir) if False in (getattr(conf, c)() for c in checks): diff --git a/config/__init__.py b/config/__init__.py index b08eb04b..704124b6 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -13,11 +13,14 @@ import platform from . import ui from . import cxx from . import python +from . import numpy from . import boost def add_options(vars): ui.add_option('-V', '--verbose', dest='verbose', action='store_true', help='verbose mode: print full commands.') + ui.add_option('--no-numpy', dest='numpy', action='store_false', help='do not attempt to build NumPy bindings.') python.add_options(vars) + numpy.add_options(vars) boost.add_options(vars) vars.Add('CXX') @@ -29,8 +32,10 @@ def add_options(vars): vars.Add('PYTHON') vars.Add('PYTHONLIBS') vars.Add('prefix') - vars.Add('boostbook_prefix', - vars.Add('CXX11')) + vars.Add('boostbook_prefix') + vars.Add('CXX11') + vars.Add('NUMPY') + vars.Add('NUMPY_CPPPATH', converter=lambda v:v.split()) ui.add_variable(vars, ("arch", "target architeture", platform.machine())) ui.add_variable(vars, ("toolchain", "toolchain to use", 'gcc')) @@ -42,10 +47,14 @@ def add_options(vars): ui.add_variable(vars, PathVariable("prefix", "Install prefix", "/usr/local", PathVariable.PathAccept)) -def get_checks(): +def get_checks(env): checks = OrderedDict() checks['cxx'] = cxx.check checks['python'] = python.check + if env.GetOption('numpy') is not False: + checks['numpy'] = numpy.check + else: + env['NUMPY'] = False checks['boost'] = boost.check return checks diff --git a/config/numpy.py b/config/numpy.py new file mode 100644 index 00000000..3380ae56 --- /dev/null +++ b/config/numpy.py @@ -0,0 +1,86 @@ +# +# Copyright (c) 2016 Stefan Seefeld +# All rights reserved. +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from . import ui +from contextlib import contextmanager + +@contextmanager +def saved(context): + save_cpppath = context.env.get('CPPPATH', []) + save_libs = context.env.get('LIBS', []) + yield context + context.env.Replace(LIBS=save_libs) + context.env.Replace(CPPPATH=save_cpppath) + + +def add_options(vars): + + pass + + +def check(context): + + numpy_source_file = r""" +// If defined, enforces linking againg PythonXXd.lib, which +// is usually not included in Python environments. +#undef _DEBUG +#include "Python.h" +#include "numpy/arrayobject.h" + +#if PY_VERSION_HEX >= 0x03000000 +void *initialize() { import_array();} +#else +void initialize() { import_array();} +#endif + +int main() +{ + int result = 0; + Py_Initialize(); + initialize(); + if (PyErr_Occurred()) + { + result = 1; + } + else + { + npy_intp dims = 2; + PyObject * a = PyArray_SimpleNew(1, &dims, NPY_INT); + if (!a) result = 1; + Py_DECREF(a); + } + Py_Finalize(); + return result; +} +""" + + import platform + import subprocess + import re, os + + def check_python(cmd): + try: + return True, subprocess.check_output([python, '-c', cmd]).strip() + except subprocess.CalledProcessError as e: + return False, e + + context.Message('Checking for NumPy...') + with saved(context): + python = context.env['PYTHON'] + result, numpy_incpath = check_python('import numpy; print(numpy.get_include())') + if result: + context.env.AppendUnique(CPPPATH=numpy_incpath) + context.env.AppendUnique(LIBS=context.env['PYTHONLIBS']) + result, output = context.TryRun(numpy_source_file,'.cpp') + if not result: + context.Result(0) + return False + context.env['NUMPY'] = True + context.env['NUMPY_CPPPATH'] = numpy_incpath + context.Result(1) + return True diff --git a/config/tools/doc.py b/config/tools/doc.py index e96f089a..5e81f379 100644 --- a/config/tools/doc.py +++ b/config/tools/doc.py @@ -58,6 +58,10 @@ def BoostRST(env, target, source, resources=[]): 'rst2html --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript --stylesheet=rst.css $SOURCE $TARGET') +def BoostSphinx(env, target, source): + env.Sphinx(target, source) + + def exists(env): return True @@ -68,3 +72,4 @@ def generate(env): env.AddMethod(BoostBook) env.AddMethod(BoostHTML) env.AddMethod(BoostRST) + env.AddMethod(BoostSphinx) diff --git a/config/tools/sphinx4scons.py b/config/tools/sphinx4scons.py new file mode 100644 index 00000000..dda88d23 --- /dev/null +++ b/config/tools/sphinx4scons.py @@ -0,0 +1,592 @@ +"""SCons.Tool.spinx4scons + +Tool-specific initialization for the Sphinx document build system. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +It should be placed in e.g. ~/site_scons/site_tools/sphinx4scons/ +directory. Then it may be loaded by placing + + sphinx = Tool('sphinx4scons') + sphinx(env) + +in your SConstruct file. + +For further details, please see the SCons documentation on how to +install and enable custom tools. +""" + +# +# This package is provided under the Expat license +# +# Copyright (c) 2012 Orlando Wingbrant +# +# 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. +# + +__author__ = "Orlando Wingbrant" +__email__ = "orlando@widesite.org" +__url__ = "https://bitbucket.org/wingbrant/sphinx4scons" +__license__ = "Expat license" + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Util +import SCons.Node.FS +import os + +from sphinx.util.matching import patfilter, compile_matchers +from sphinx.util.osutil import make_filename + + +class ToolSphinxWarning(SCons.Warnings.Warning): + pass + + +class SphinxBuilderNotFound(ToolSphinxWarning): + pass + +SCons.Warnings.enableWarningClass(ToolSphinxWarning) + + +def exists(env): + return _detect(env) + + +def _detect(env): + """Try to detect the sphinx-build script.""" + try: + return env['SPHINXBUILD'] + except KeyError: + pass + + sphinx = env.WhereIs('sphinx-build') + if sphinx: + return sphinx + + raise SCons.Errors.StopError( + SphinxBuilderNotFound, + "Could not detect sphinx-build script") + return None + + +def generate(env): + """Add Builders and construction variables to the Environment.""" + + env['SPHINXBUILD'] = _detect(env) + sphinx = _create_sphinx_builder(env) + + env.SetDefault( + # Additional command-line flags + SPHINXFLAGS = '', + + # Tag definitions, each entry will appear on the command line preceded by -t + SPHINXTAGS = [], + + # Directory for doctrees + SPHINXDOCTREE = '', + + # Path to sphinx configuration file + SPHINXCONFIG = '', + + # Config file override settings, each entry will be preceded by -D + SPHINXSETTINGS = {}, + + # Default sphinx builder, + SPHINXBUILDER = 'html', + + # Sphinx command + SPHINXCOM = "$SPHINXBUILD $_SPHINXOPTIONS ${SOURCE.attributes.root} ${TARGET.attributes.root}", + + # Alternate console output when building sphinx documents + SPHINXCOMSTR = "" + ) + + try: + env.AddMethod(Sphinx, "Sphinx") + except AttributeError: + # Looks like we use a pre-0.98 version of SCons... + from SCons.Script.SConscript import SConsEnvironment + SConsEnvironment.Sphinx = Sphinx + + +def Sphinx(env, target, source, **kw): + """A pseudo-builder wrapper for the sphinx builder.""" + builder = env['BUILDERS']['Sphinx4Scons'] + env_kw = env.Override(kw) + options = _get_sphinxoptions(env_kw, target, source) + output = builder(env, target, source, _SPHINXOPTIONS=options, **kw) + return output + + +def _get_sphinxoptions(env, target, source): + """Concatenates all the options for the sphinx command line.""" + options = [] + + builder = _get_sphinxbuilder(env) + options.append("-b %s" % env.subst(builder, target=target, source=source)) + + flags = env.get('options', env.get('SPHINXFLAGS', '')) + options.append(env.subst(flags, target=target, source=source)) + + tags = env.get('tags', env.get('SPHINXTAGS', None)) + if tags is not None: + if not SCons.SCons.Util.is_List(tags): + tags = [tags] + for tag in tags: + if tag != '': + tag = env.subst(tag, target=target, source=source) + options.append("-t %s" % tag) + + settings = env.get('settings', env.get('SPHINXSETTINGS', None)) + if settings is not None: + if not SCons.SCons.Util.is_Dict(settings): + raise TypeError('SPHINXSETTINGS and/or settings argument must be a dictionary') + for key, value in settings.iteritems(): + if value != '': + value = env.subst(value, target=target, source=source) + options.append('-D "%s=%s"' % (key, value)) + + doctree = env.get('doctree', env.get("SPHINXDOCTREE", None)) + if isinstance(doctree, SCons.Node.FS.Dir): + options.append("-d %s" % doctree.get_abspath()) + elif doctree is not None and doctree != '': + doctree = env.subst(doctree, target=target, source=source) + options.append("-d %s" % env.Dir(doctree).get_abspath()) + + config = _get_sphinxconfig_path(env, None) + if config is not None and config != '': + config = env.subst(config, target=target, source=source) + options.append("-c %s" % env.Dir(config).File('conf.py').rfile().dir.get_abspath()) + return " ".join(options) + + +def _create_sphinx_builder(env): + try: + sphinx = env['BUILDERS']['Sphinx4Scons'] + except KeyError: + fs = SCons.Node.FS.get_default_fs() + sphinx_com = SCons.Action.Action('$SPHINXCOM', '$SPHINXCOMSTR') + sphinx = SCons.Builder.Builder(action=sphinx_com, + emitter=sphinx_emitter, + target_factory=fs.Dir, + source_factory=fs.Dir + ) + env['BUILDERS']['Sphinx4Scons'] = sphinx + return sphinx + + +def sphinx_emitter(target, source, env): + target[0].must_be_same(SCons.Node.FS.Dir) + targetnode = target[0] + + source[0].must_be_same(SCons.Node.FS.Dir) + srcnode = source[0] + + configdir = _get_sphinxconfig_path(env, None) + if not configdir: + confignode = srcnode + else: + confignode = env.Dir(configdir) + + srcinfo = SourceInfo(srcnode, confignode, env) + targets, sources = _get_emissions(env, target, srcinfo) + env.Clean(targets, target[0]) + + return targets, sources + + +def sphinx_path(os_path): + """Create sphinx-style path from os-style path.""" + return os_path.replace(os.sep, "/") + + +def os_path(sphinx_path): + """Create os-style path from sphinx-style path.""" + return sphinx_path.replace("/", os.sep) + + +class SourceInfo(object): + """ + Data container for all different kinds of source files used in + a sphinx project. + """ + def __init__(self, srcnode, confignode, env): + self.confignode = confignode + self.config = self._get_config(self.confignode, env) + self.templates = self._get_templates(self.confignode, self.config) + self.statics = self._get_statics(self.confignode, self.config) + self.srcnode = srcnode + self.sources = self._get_sources(self.srcnode, self.config) + + self.srcroot = srcnode + if not srcnode.duplicate: + self.srcroot = srcnode.srcnode().rdir() + + + def _get_config(self, confignode, env): + config = {} + execfile(confignode.File('conf.py').rfile().get_abspath(), config) + return config + + + def _get_templates(self, confignode, config): + """Returns template files defined in the project.""" + templates = [] + for path in config.get('templates_path', []): + # Check if path is dir or file. + # We can't use FS.Entry since that will create nodes, and + # these nodes don't know about the source tree and will + # get disambiguated to files even if they are directories in the + # source tree. + p = confignode.File('conf.py').rfile().dir.srcnode().get_abspath() + p = os.path.join(p, os_path(path)) + if os.path.isfile(p): + templates.append(confignode.File(path)) + elif os.path.isdir(p): + node = confignode.Dir(path) + for root, dirs, files in os.walk(p): + mydir = node.Dir(os.path.relpath(root, p)) + templates += [mydir.File(f) for f in files] + return templates + + + def _get_statics(self, confignode, config): + """Returns static files, filtered through exclude_patterns.""" + statics = [] + matchers = compile_matchers(config.get('exclude_patterns', [])) + + for path in config.get('html_static_path', []): + # Check _get_templates() why we use this construction. + p = confignode.File('conf.py').rfile().dir.srcnode().get_abspath() + p = os.path.join(p, os_path(path)) + if os.path.isfile(p): + statics.append(confignode.File(path)) + elif os.path.isdir(p): + node = confignode.Dir(path) + for root, dirs, files in os.walk(p): + relpath = os.path.relpath(root, p) + for entry in [d for d in dirs if + self._anymatch(matchers, + sphinx_path(os.path.join(relpath, d)))]: + dirs.remove(entry) + statics += [node.File(os_path(f)) for f in + self._exclude(matchers, + [sphinx_path(os.path.join(relpath, name)) + for name in files])] + return statics + + + def _get_sources(self, srcnode, config): + """Returns all source files in the project filtered through exclude_patterns.""" + suffix = config.get('source_suffix', '.rst') + matchers = compile_matchers(config.get('exclude_patterns', [])) + + srcfiles = [] + scannode = srcnode.srcnode().rdir() + + for root, dirs, files in os.walk(scannode.get_abspath()): + relpath = os.path.relpath(root, scannode.get_abspath()) + for entry in [d for d in dirs if + self._anymatch(matchers, + sphinx_path(os.path.join(relpath, d)))]: + dirs.remove(entry) + srcfiles += [srcnode.File(os_path(f)) for f in + self._exclude(matchers, + [sphinx_path(os.path.join(relpath, name)) + for name in files if name.endswith(suffix)])] + return srcfiles + + + def _exclude(self, matchers, items): + result = items + for matcher in matchers: + result = filter(lambda x: not matcher(x), result) + return result + + + def _anymatch(self, matchers, item): + for matcher in matchers: + if matcher(item): + return True + return False + + +def _get_sphinxconfig_path(env, default): + path = env.get('config', env.get('SPHINXCONFIG', None)) + if path is None or path == '': + path = default + return path + + +def _get_emissions(env, target, srcinfo): + targets = [] + sources = [] + builder = _get_sphinxbuilder(env) + if builder == 'changes': + targets, sources = _get_changes_emissions(env, target, srcinfo) + if builder == 'devhelp': + targets, sources = _get_help_emissions(env, target, srcinfo, + ['.devhelp.gz']) + elif builder == 'dirhtml': + targets, sources = _get_dirhtml_emissions(env, target, srcinfo) + elif builder == 'doctest': + targets, sources = _get_doctest_emissions(env, target, srcinfo) + elif builder == 'epub': + targets, sources = _get_epub_emissions(env, target, srcinfo) + elif builder == 'html': + targets, sources = _get_serialize_emissions(env, target, srcinfo) + elif builder == 'htmlhelp': + targets, sources = _get_help_emissions(env, target, srcinfo, + ['.hhp'], 'htmlhelp_basename') + elif builder == 'gettext': + targets, sources = _get_gettext_emissions(env, target, srcinfo) + elif builder == 'json': + targets, sources = _get_serialize_emissions(env, target, srcinfo, + '.fjson', + ['globalcontext.json', + 'searchindex.json', + 'self.environment.pickle']) + elif builder == 'latex': + targets, sources = _get_latex_emissions(env, target, srcinfo) + elif builder == 'linkcheck': + targets, sources = _get_linkcheck_emissions(env, target, srcinfo) + elif builder == 'man': + targets, sources = _get_man_emissions(env, target, srcinfo) + elif builder == 'pickle': + targets, sources = _get_serialize_emissions(env, target, srcinfo, + '.fpickle', + ['globalcontext.pickle', + 'searchindex.pickle', + 'environment.pickle']) + elif builder == 'qthelp': + targets, sources = _get_help_emissions(env, target, srcinfo, + ['.qhp', '.qhcp']) + elif builder == 'singlehtml': + targets, sources = _get_singlehtml_emissions(env, target, srcinfo) + elif builder == 'texinfo': + targets, sources = _get_texinfo_emissions(env, target, srcinfo) + elif builder == 'text': + targets, sources = _get_text_emissions(env, target, srcinfo) + + sources.append(srcinfo.confignode.File('conf.py')) + + for s in sources: + s.attributes.root = srcinfo.srcroot + + for t in targets: + t.attributes.root = target[0] + + return targets, sources + + +def _get_sphinxbuilder(env): + builder = env.get('builder', env["SPHINXBUILDER"]) + if builder is None or builder == '': + raise SCons.Errors.UserError(("Missing construction variable " + + "SPHINXBUILDER or variable is empty.")) + return builder + + +def _get_changes_emissions(env, target, srcinfo): + sources = [] + sources.extend(srcinfo.sources) + targets = [target[0].File("changes.html")] + return targets, sources + + +def _get_dirhtml_emissions(env, target, srcinfo): + suffix = srcinfo.config.get('html_file_suffix', ".html") + + def get_outfilename(pagename): + pagename = os.path.splitext(pagename)[0] + + #Special treatment of files named "index". Don't create directory. + if pagename == 'index' or pagename.endswith(os.sep + 'index'): + outfilename = pagename + suffix + else: + outfilename = os.path.join(pagename, 'index' + suffix) + return outfilename + + sources = [] + sources.extend(srcinfo.sources) + sources.extend(srcinfo.templates) + sources.extend(srcinfo.statics) + + targets = [] + for s in srcinfo.sources: + t = os.path.relpath(str(s), str(srcinfo.srcroot)) + targets.append(target[0].File(get_outfilename(t))) + + for key in srcinfo.config.get('html_additional_pages', {}): + t = target[0].File(get_outfilename(key)) + targets.append(t) + + return targets, sources + + +def _get_doctest_emissions(env, target, srcinfo): + sources = [] + sources.extend(srcinfo.sources) + targets = [target[0].File("output.txt")] + return targets, sources + + +def _get_epub_emissions(env, target, srcinfo): + epubPreFiles = srcinfo.config.get('epub_pre_files', []) + epubPostFiles = srcinfo.config.get('epub_post_files', []) + epubCover = srcinfo.config.get('epub_cover', (None, None)) + + sources = [] + sources.extend(srcinfo.sources) + sources.extend([srcinfo.srcroot.File(os_path(f[0])) for f in epubPreFiles]) + sources.extend([srcinfo.srcroot.File(os_path(f[0])) for f in epubPostFiles]) + if not (epubCover[0] is None or epubCover[0] == ''): + sources.append(srcinfo.srcroot.File(os_path(epubCover[0]))) + if not (epubCover[1] is None or epubCover[1] == ''): + sources.append(srcinfo.srcroot.File(os_path(epubCover[1]))) + + t = srcinfo.config.get('epub_basename', + srcinfo.config.get('project', + 'Python')) + + targets = [target[0].File("%s.epub" % make_filename(t))] + + return targets, sources + + +def _get_gettext_emissions(env, target, srcinfo): + sources = [] + sources.extend(srcinfo.sources) + + targets = [os.path.relpath(str(s), str(srcinfo.srcroot)) for s in sources] + targets = [os.path.splitext(t)[0] for t in targets] + targets = set([t.split(os.sep)[0] for t in targets]) + targets = [target[0].File(t + ".pot") for t in targets] + + return targets, sources + + +def _get_help_emissions(env, target, srcinfo, suffixes, basenameConfigKey='project'): + basename = make_filename( + srcinfo.config.get(basenameConfigKey, srcinfo.config['project'])) + + sources = [] + sources.extend(srcinfo.sources) + sources.extend(srcinfo.templates) + sources.extend(srcinfo.statics) + + targets = [target[0].File(basename + s) for s in suffixes] + + return targets, sources + + +def _get_latex_emissions(env, target, srcinfo): + sources = [] + sources.extend(srcinfo.sources) + + targets = map(lambda x: target[0].File(os_path(x[1])), + srcinfo.config.get('latex_documents')) + + return targets, sources + + +def _get_linkcheck_emissions(env, target, srcinfo): + sources = [] + sources.extend(srcinfo.sources) + targets = [target[0].File("output.txt")] + return targets, sources + + +def _get_man_emissions(env, target, srcinfo): + sources = [] + sources.extend(srcinfo.sources) + targets = map(lambda x: target[0].File(os_path("%s.%s" % (x[1], x[4]))), + srcinfo.config.get('man_pages')) + return targets, sources + + +def _get_serialize_emissions(env, target, srcinfo, suffix=None, extrafiles=[]): + if suffix is None: + suffix = srcinfo.config.get('html_file_suffix', '.html') + + sources = [] + sources.extend(srcinfo.sources) + sources.extend(srcinfo.templates) + sources.extend(srcinfo.statics) + + targets = [] + for s in srcinfo.sources: + t = os.path.splitext(str(s))[0] + suffix + t = os.path.relpath(t, str(srcinfo.srcroot)) + targets.append(t) + + for key in srcinfo.config.get('html_additional_pages', {}): + targets.append(os_path("%s%s" % (key, suffix))) + + targets.extend(extrafiles) + targets = [target[0].File(t) for t in targets] + + return targets, sources + + +def _get_singlehtml_emissions(env, target, srcinfo): + suffix = srcinfo.config.get('html_file_suffix', ".html") + + sources = [] + sources.extend(srcinfo.sources) + sources.extend(srcinfo.templates) + sources.extend(srcinfo.statics) + + t = os.path.relpath(srcinfo.config['master_doc'] + suffix, + str(srcinfo.srcroot)) + targets = [target[0].File(t)] + + return targets, sources + + +def _get_texinfo_emissions(env, target, srcinfo): + suffix = srcinfo.config.get('source_suffix', '.rst') + + sources = [] + sources.extend(srcinfo.sources) + sources.extend(map(lambda x: source[0].File(os_path(x + suffix)), + srcinfo.config.get('texinfo_appendices', []))) + + targets = map(lambda x: target[0].File(os_path("%s.texi" % x[1])), + srcinfo.config.get('texinfo_documents')) + + return targets, sources + + +def _get_text_emissions(env, target, srcinfo): + sources = [] + sources.extend(srcinfo.sources) + + targets = [] + for s in sources: + t = os.path.relpath(str(s), str(srcinfo.srcroot)) + t = os.path.splitext(t)[0] + ".txt" + targets.append(target[0].File(t)) + + return targets, sources diff --git a/doc/SConscript b/doc/SConscript index e22b3fc2..8eb0fb93 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -47,3 +47,6 @@ env.BoostHTML('html/reference/', 'reference.dbk', '--stringparam', 'boost.graphics.root', '../images/']) env.BoostRST('html/article.html', 'article.rst', resources=['rst.css']) + +if env['NUMPY']: + env.BoostSphinx('html/numpy', 'numpy/') diff --git a/doc/numpy/_static/bpl.png b/doc/numpy/_static/bpl.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d8c69e00ca3aada62024809e20d138a8906875 GIT binary patch literal 21289 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 -

C++ Boost

-

Boost.NumPy

+ diff --git a/doc/numpy/conf.py b/doc/numpy/conf.py index 84e20f4c..6ee1a921 100644 --- a/doc/numpy/conf.py +++ b/doc/numpy/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Boost.NumPy documentation build configuration file, created by +# Boost.Python NumPy documentation build configuration file, created by # sphinx-quickstart on Thu Oct 27 09:04:58 2011. # # This file is execfile()d with the current directory set to its containing dir. @@ -40,7 +40,7 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'Boost.NumPy' +project = u'Boost.Python NumPy extension' copyright = u'2011, Stefan Seefeld' # The version info for the project you're documenting, acts as replacement for @@ -112,7 +112,7 @@ html_theme = 'default' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = '_static/boost.png' +html_logo = 'static/bpl.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -122,7 +122,7 @@ html_logo = '_static/boost.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ['static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. @@ -166,7 +166,7 @@ html_use_index = True #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'BoostNumPydoc' +htmlhelp_basename = 'BoostPythonNumPydoc' html_add_permalinks = False @@ -181,7 +181,7 @@ html_add_permalinks = False # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'BoostNumPy.tex', u'Boost.NumPy Documentation', + ('index', 'BoostPythonNumPy.tex', u'Boost.Python NumPy Documentation', u'Stefan Seefeld', 'manual'), ] @@ -214,6 +214,6 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'boostnumpy', u'Boost.NumPy Documentation', + ('index', 'boostnumpy', u'Boost.Python NumPy Documentation', [u'Stefan Seefeld'], 1) ] diff --git a/doc/numpy/index.rst b/doc/numpy/index.rst index 8456fc32..671a7b6c 100644 --- a/doc/numpy/index.rst +++ b/doc/numpy/index.rst @@ -1,10 +1,10 @@ -.. Boost.NumPy documentation master file, created by +.. Boost.Python NumPy extension documentation master file, created by sphinx-quickstart on Thu Oct 27 09:04:58 2011. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to Boost.NumPy's documentation! -======================================= +Welcome to the documentation of the Boost.Python NumPy extension! +================================================================= Contents: @@ -13,5 +13,4 @@ Contents: Tutorial Reference - cmakeBuild.rst diff --git a/doc/numpy/reference/binary_ufunc.rst b/doc/numpy/reference/binary_ufunc.rst index 23a36f77..988df2e9 100644 --- a/doc/numpy/reference/binary_ufunc.rst +++ b/doc/numpy/reference/binary_ufunc.rst @@ -5,7 +5,7 @@ binary_ufunc A ``binary_ufunc`` is a struct used as an intermediate step to broadcast two arguments so that a C++ function can be converted to a ufunc like function - ```` contains the ``binary_ufunc`` structure definitions + ```` contains the ``binary_ufunc`` structure definitions synopsis @@ -15,6 +15,8 @@ synopsis namespace boost { + namespace python + { namespace numpy { @@ -26,16 +28,17 @@ synopsis struct binary_ufunc { - static python::object call(TBinaryFunctor & self, - python::object const & input1, - python::object const & input2, - python::object const & output); + static object call(TBinaryFunctor & self, + object const & input1, + object const & input2, + object const & output); - static python::object make(); + static object make(); }; } } + } constructors @@ -63,9 +66,9 @@ accessors typename TArgument1=typename TBinaryFunctor::first_argument_type, typename TArgument2=typename TBinaryFunctor::second_argument_type, typename TResult=typename TBinaryFunctor::result_type> - static python::object call(TBinaryFunctor & self, - python::object const & input, - python::object const & output); + static object call(TBinaryFunctor & self, + object const & input, + object const & output); :Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type @@ -77,7 +80,7 @@ accessors typename TArgument1=typename TBinaryFunctor::first_argument_type, typename TArgument2=typename TBinaryFunctor::second_argument_type, typename TResult=typename TBinaryFunctor::result_type> - static python::object make(); + static object make(); :Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type @@ -87,6 +90,8 @@ Example(s) ---------- :: + namespace p = boost::python; + namespace np = boost::python::numpy; struct BinarySquare { diff --git a/doc/numpy/reference/dtype.rst b/doc/numpy/reference/dtype.rst index b76e79a4..6491dfd7 100644 --- a/doc/numpy/reference/dtype.rst +++ b/doc/numpy/reference/dtype.rst @@ -7,7 +7,7 @@ A `dtype`_ is an object describing the type of the elements of an ndarray .. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype - ```` contains the method calls necessary to generate a python object equivalent to a numpy.dtype from builtin C++ objects, as well as to create custom dtypes from user defined types + ```` contains the method calls necessary to generate a python object equivalent to a numpy.dtype from builtin C++ objects, as well as to create custom dtypes from user defined types synopsis @@ -17,12 +17,14 @@ synopsis namespace boost { + namespace python + { namespace numpy { - class dtype : public python::object + class dtype : public object { - static python::detail::new_reference convert(python::object::object_cref arg, bool align); + static python::detail::new_reference convert(object::object_cref arg, bool align); public: // Convert an arbitrary Python object to a data-type descriptor object. @@ -37,6 +39,8 @@ synopsis }; } + } + } constructors ------------ @@ -78,8 +82,9 @@ Example(s) ---------- :: + namespace p = boost::python; + namespace np = boost::python::numpy; - namespace np = boost::numpy; np::dtype dtype = np::dtype::get_builtin(); p::tuple for_custom_dtype = p::make_tuple("ha",dtype); np::dtype custom_dtype = np::dtype(list_for_dtype); diff --git a/doc/numpy/reference/index.rst b/doc/numpy/reference/index.rst index 27de3ee2..9562f864 100644 --- a/doc/numpy/reference/index.rst +++ b/doc/numpy/reference/index.rst @@ -1,5 +1,5 @@ -Boost.NumPy Reference -===================== +Boost.Python NumPy extension Reference +====================================== Contents: diff --git a/doc/numpy/reference/multi_iter.rst b/doc/numpy/reference/multi_iter.rst index 610f91ee..659f61f4 100644 --- a/doc/numpy/reference/multi_iter.rst +++ b/doc/numpy/reference/multi_iter.rst @@ -5,7 +5,7 @@ multi_iter A ``multi_iter`` is a Python object, intended to be used as an iterator It should generally only be used in loops. - ```` contains the class definitions for ``multi_iter`` + ```` contains the class definitions for ``multi_iter`` synopsis @@ -15,10 +15,12 @@ synopsis namespace boost { + namespace python + { namespace numpy { - class multi_iter : public python::object + class multi_iter : public object { public: void next(); @@ -30,12 +32,13 @@ synopsis }; - multi_iter make_multi_iter(python::object const & a1); - multi_iter make_multi_iter(python::object const & a1, python::object const & a2); - multi_iter make_multi_iter(python::object const & a1, python::object const & a2, python::object const & a3); + multi_iter make_multi_iter(object const & a1); + multi_iter make_multi_iter(object const & a1, object const & a2); + multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3); } } + } constructors @@ -43,9 +46,9 @@ constructors :: - multi_iter make_multi_iter(python::object const & a1); - multi_iter make_multi_iter(python::object const & a1, python::object const & a2); - multi_iter make_multi_iter(python::object const & a1, python::object const & a2, python::object const & a3); + multi_iter make_multi_iter(object const & a1); + multi_iter make_multi_iter(object const & a1, object const & a2); + multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3); :Returns: A Python iterator object broadcasting over one, two or three sequences as supplied diff --git a/doc/numpy/reference/ndarray.rst b/doc/numpy/reference/ndarray.rst index 9b470392..b22f0bbf 100644 --- a/doc/numpy/reference/ndarray.rst +++ b/doc/numpy/reference/ndarray.rst @@ -8,7 +8,7 @@ A `ndarray`_ is an N-dimensional array which contains items of the same type and .. _ndarray: http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html .. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype - ```` contains the structures and methods necessary to move raw data between C++ and Python and create ndarrays from the data + ```` contains the structures and methods necessary to move raw data between C++ and Python and create ndarrays from the data @@ -19,10 +19,12 @@ synopsis namespace boost { + namespace python + { namespace numpy { - class ndarray : public python::object + class ndarray : public object { public: @@ -53,30 +55,30 @@ synopsis ndarray transpose() const; ndarray squeeze() const; - ndarray reshape(python::tuple const & shape) const; - python::object scalarize() const; + ndarray reshape(tuple const & shape) const; + object scalarize() const; }; - ndarray zeros(python::tuple const & shape, dtype const & dt); + ndarray zeros(tuple const & shape, dtype const & dt); ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt); - ndarray empty(python::tuple const & shape, dtype const & dt); + ndarray empty(tuple const & shape, dtype const & dt); ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt); - ndarray array(python::object const & obj); - ndarray array(python::object const & obj, dtype const & dt); + ndarray array(object const & obj); + ndarray array(object const & obj, dtype const & dt); template ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner); template - ndarray from_data(void const * data, dtype const & dt, Container shape, Container strides, python::object const & owner); + ndarray from_data(void const * data, dtype const & dt, Container shape, Container strides, object const & owner); - ndarray from_object(python::object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); - ndarray from_object(python::object const & obj, dtype const & dt,int nd, ndarray::bitflag flags=ndarray::NONE); - ndarray from_object(python::object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE); - ndarray from_object(python::object const & obj, int nd_min, int nd_max,ndarray::bitflag flags=ndarray::NONE); - ndarray from_object(python::object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE); - ndarray from_object(python::object const & obj, ndarray::bitflag flags=ndarray::NONE) + ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); + ndarray from_object(object const & obj, dtype const & dt,int nd, ndarray::bitflag flags=ndarray::NONE); + ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE); + ndarray from_object(object const & obj, int nd_min, int nd_max,ndarray::bitflag flags=ndarray::NONE); + ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE); + ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE) ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b) ; ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b); @@ -119,7 +121,7 @@ constructors :: - ndarray reshape(python::tuple const & shape) const; + ndarray reshape(tuple const & shape) const; :Requirements: The new ``shape`` of the ndarray must be supplied as a tuple @@ -128,13 +130,13 @@ constructors :: - python::object scalarize() const; + object scalarize() const; :Returns: A scalar if the ndarray has only one element, otherwise it returns the entire array :: - ndarray zeros(python::tuple const & shape, dtype const & dt); + ndarray zeros(tuple const & shape, dtype const & dt); ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt); :Requirements: The following parameters must be supplied as required : @@ -148,7 +150,7 @@ constructors :: - ndarray empty(python::tuple const & shape, dtype const & dt); + ndarray empty(tuple const & shape, dtype const & dt); ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt); @@ -162,8 +164,8 @@ constructors :: - ndarray array(python::object const & obj); - ndarray array(python::object const & obj, dtype const & dt); + ndarray array(object const & obj); + ndarray array(object const & obj, dtype const & dt); :Returns: A new ndarray from an arbitrary Python sequence, with dtype of each element specified optionally @@ -186,7 +188,7 @@ constructors :: - ndarray from_object(python::object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); + ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); :Requirements: The following parameters must be supplied : @@ -200,7 +202,7 @@ constructors :: - inline ndarray from_object(python::object const & obj, dtype const & dt, int nd, ndarray::bitflag flags=ndarray::NONE); + inline ndarray from_object(object const & obj, dtype const & dt, int nd, ndarray::bitflag flags=ndarray::NONE); :Requirements: The following parameters must be supplied : @@ -213,7 +215,7 @@ constructors :: - inline ndarray from_object(python::object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE) + inline ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE) :Requirements: The following parameters must be supplied : @@ -225,7 +227,7 @@ constructors :: - ndarray from_object(python::object const & obj, int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); + ndarray from_object(object const & obj, int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); :Requirements: The following parameters must be supplied : @@ -240,7 +242,7 @@ constructors :: - inline ndarray from_object(python::object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE); + inline ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE); :Requirements: The following parameters must be supplied : @@ -253,7 +255,7 @@ constructors :: - inline ndarray from_object(python::object const & obj, ndarray::bitflag flags=ndarray::NONE) + inline ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE) :Requirements: The following parameters must be supplied : @@ -295,7 +297,7 @@ accessors :: - python::object get_base() const; + object get_base() const; :Returns: Object that owns the array's data, or None if the array owns its own data. @@ -351,6 +353,8 @@ Example(s) ---------- :: + namespace p = boost::python; + namespace np = boost::python::numpy; p::object tu = p::make_tuple('a','b','c') ; np::ndarray example_tuple = np::array (tu) ; diff --git a/doc/numpy/reference/unary_ufunc.rst b/doc/numpy/reference/unary_ufunc.rst index 1cdf6c75..b1d88555 100644 --- a/doc/numpy/reference/unary_ufunc.rst +++ b/doc/numpy/reference/unary_ufunc.rst @@ -5,7 +5,7 @@ unary_ufunc A ``unary_ufunc`` is a struct used as an intermediate step to broadcast a single argument so that a C++ function can be converted to a ufunc like function - ```` contains the ``unary_ufunc`` structure definitions + ```` contains the ``unary_ufunc`` structure definitions synopsis @@ -15,6 +15,8 @@ synopsis namespace boost { + namespace python + { namespace numpy { @@ -24,15 +26,16 @@ synopsis struct unary_ufunc { - static python::object call(TUnaryFunctor & self, - python::object const & input, - python::object const & output) ; + static object call(TUnaryFunctor & self, + object const & input, + object const & output) ; - static python::object make(); + static object make(); }; } } + } constructors @@ -58,9 +61,9 @@ accessors template - static python::object call(TUnaryFunctor & self, - python::object const & input, - python::object const & output); + static object call(TUnaryFunctor & self, + object const & input, + object const & output); :Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type @@ -71,7 +74,7 @@ accessors template - static python::object make(); + static object make(); :Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type @@ -83,6 +86,8 @@ Example(s) ---------- :: + namespace p = boost::python; + namespace np = boost::python::numpy; struct UnarySquare { diff --git a/doc/numpy/tutorial/dtype.rst b/doc/numpy/tutorial/dtype.rst index 02bb513b..34008d19 100644 --- a/doc/numpy/tutorial/dtype.rst +++ b/doc/numpy/tutorial/dtype.rst @@ -5,11 +5,11 @@ Here is a brief tutorial to show how to create ndarrays with built-in python dat Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module:: - #include + #include #include namespace p = boost::python; - namespace np = boost::numpy; + namespace np = boost::python::numpy; int main(int argc, char **argv) { diff --git a/doc/numpy/tutorial/fromdata.rst b/doc/numpy/tutorial/fromdata.rst index d2e59fa0..4f18997e 100644 --- a/doc/numpy/tutorial/fromdata.rst +++ b/doc/numpy/tutorial/fromdata.rst @@ -6,11 +6,11 @@ The from_data method makes this possible. Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module:: - #include + #include #include namespace p = boost::python; - namespace np = boost::numpy; + namespace np = boost::python::numpy; int main(int argc, char **argv) { diff --git a/doc/numpy/tutorial/index.rst b/doc/numpy/tutorial/index.rst index ca15971c..c54c8fa2 100644 --- a/doc/numpy/tutorial/index.rst +++ b/doc/numpy/tutorial/index.rst @@ -1,5 +1,5 @@ -Boost.NumPy Tutorial -==================== +Boost.Python NumPy extension Tutorial +===================================== Contents: diff --git a/doc/numpy/tutorial/ndarray.rst b/doc/numpy/tutorial/ndarray.rst index 02e732cd..d944ae43 100644 --- a/doc/numpy/tutorial/ndarray.rst +++ b/doc/numpy/tutorial/ndarray.rst @@ -8,11 +8,11 @@ This tutorial will introduce you to some of the ways in which you can create nda First, as before, initialise the necessary namepaces and runtimes :: - #include + #include #include namespace p = boost::python; - namespace np = boost::numpy; + namespace np = boost::python::numpy; int main(int argc, char **argv) { diff --git a/doc/numpy/tutorial/simple.rst b/doc/numpy/tutorial/simple.rst index 3c462962..889eea11 100644 --- a/doc/numpy/tutorial/simple.rst +++ b/doc/numpy/tutorial/simple.rst @@ -5,11 +5,11 @@ Let's start with a simple tutorial to create and modify arrays. Get the necessary headers for numpy components and set up necessary namespaces:: - #include + #include #include namespace p = boost::python; - namespace np = boost::numpy; + namespace np = boost::python::numpy; Initialise the Python runtime, and the numpy module. Failure to call these results in segmentation errors:: diff --git a/doc/numpy/tutorial/ufunc.rst b/doc/numpy/tutorial/ufunc.rst index 1943e675..47acafb4 100644 --- a/doc/numpy/tutorial/ufunc.rst +++ b/doc/numpy/tutorial/ufunc.rst @@ -7,11 +7,11 @@ Lets try and see how we can use the binary and unary ufunc methods After the neccessary includes :: - #include + #include #include namespace p = boost::python; - namespace np = boost::numpy; + namespace np = boost::python::numpy; Now we create the structs necessary to implement the ufuncs. The typedefs *must* be made as the ufunc generators take these typedefs as inputs and return an error otherwise :: diff --git a/doc/python.qbk b/doc/python.qbk index 0a3b7d0d..fc07b2c0 100644 --- a/doc/python.qbk +++ b/doc/python.qbk @@ -50,6 +50,7 @@ The development of these features was funded in part by grants to `Boost Consult * [link glossary Glossary] * [link support Support Resources] * [link faq Frequently Asked Questions (FAQs)] +* [@numpy/index.html NumPy] [endsect] diff --git a/include/boost/python/numpy.hpp b/include/boost/python/numpy.hpp index e4fb087e..cd5876a8 100644 --- a/include/boost/python/numpy.hpp +++ b/include/boost/python/numpy.hpp @@ -1,24 +1,20 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_HPP_INCLUDED -#define BOOST_NUMPY_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -/** - * @file boost/numpy.hpp - * @brief Main public header file for boost.numpy. - */ +#ifndef boost_python_numpy_hpp_ +#define boost_python_numpy_hpp_ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -namespace boost { -namespace numpy { +namespace boost { namespace python { namespace numpy { /** * @brief Initialize the Numpy C-API @@ -32,7 +28,6 @@ namespace numpy { */ void initialize(bool register_scalar_converters=true); -} // namespace boost::numpy -} // namespace boost +}}} // namespace boost::python::numpy -#endif // !BOOST_NUMPY_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/dtype.hpp b/include/boost/python/numpy/dtype.hpp index 9d92f008..1284f9e5 100644 --- a/include/boost/python/numpy/dtype.hpp +++ b/include/boost/python/numpy/dtype.hpp @@ -1,35 +1,37 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_DTYPE_HPP_INCLUDED -#define BOOST_NUMPY_DTYPE_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_dtype_hpp_ +#define boost_python_numpy_dtype_hpp_ /** - * @file boost/numpy/dtype.hpp + * @file boost/python/numpy/dtype.hpp * @brief Object manager for Python's numpy.dtype class. */ #include -#include +#include #include #include -namespace boost { namespace numpy { +namespace boost { namespace python { namespace numpy { /** * @brief A boost.python "object manager" (subclass of object) for numpy.dtype. * * @todo This could have a lot more interesting accessors. */ -class dtype : public python::object { - static python::detail::new_reference convert(python::object::object_cref arg, bool align); +class dtype : public object { + static python::detail::new_reference convert(object::object_cref arg, bool align); public: /// @brief Convert an arbitrary Python object to a data-type descriptor object. template - explicit dtype(T arg, bool align=false) : python::object(convert(arg, align)) {} + explicit dtype(T arg, bool align=false) : object(convert(arg, align)) {} /** * @brief Get the built-in numpy dtype associated with the given scalar template type. @@ -63,7 +65,7 @@ public: */ static void register_scalar_converters(); - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dtype, python::object); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dtype, object); }; @@ -106,10 +108,10 @@ struct builtin_dtype< std::complex, false > { template inline dtype dtype::get_builtin() { return detail::builtin_dtype::get(); } -}} // namespace boost::numpy +} // namespace boost::python::numpy -namespace boost { namespace python { namespace converter { +namespace converter { NUMPY_OBJECT_MANAGER_TRAITS(numpy::dtype); }}} // namespace boost::python::converter -#endif // !BOOST_NUMPY_DTYPE_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/internal.hpp b/include/boost/python/numpy/internal.hpp index 400a584b..fed31cbb 100644 --- a/include/boost/python/numpy/internal.hpp +++ b/include/boost/python/numpy/internal.hpp @@ -1,23 +1,25 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_INTERNAL_HPP_INCLUDED -#define BOOST_NUMPY_INTERNAL_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_internal_hpp_ +#define boost_python_numpy_internal_hpp_ /** - * @file boost/numpy/internal.hpp + * @file boost/python/numpy/internal.hpp * @brief Internal header file to include the Numpy C-API headers. * * This should only be included by source files in the boost.numpy library itself. */ #include -#ifdef BOOST_NUMPY_INTERNAL +#ifdef BOOST_PYTHON_NUMPY_INTERNAL #define NO_IMPORT_ARRAY #define NO_IMPORT_UFUNC #else -#ifndef BOOST_NUMPY_INTERNAL_MAIN +#ifndef BOOST_PYTHON_NUMPY_INTERNAL_MAIN ERROR_internal_hpp_is_for_internal_use_only #endif #endif @@ -25,9 +27,9 @@ ERROR_internal_hpp_is_for_internal_use_only #define PY_UFUNC_UNIQUE_SYMBOL BOOST_UFUNC_ARRAY_API #include #include -#include +#include #define NUMPY_OBJECT_MANAGER_TRAITS_IMPL(pytype,manager) \ PyTypeObject const * object_manager_traits::get_pytype() { return &pytype; } -#endif // !BOOST_NUMPY_INTERNAL_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/invoke_matching.hpp b/include/boost/python/numpy/invoke_matching.hpp index 6a4dfdb1..90ec8ae2 100644 --- a/include/boost/python/numpy/invoke_matching.hpp +++ b/include/boost/python/numpy/invoke_matching.hpp @@ -1,24 +1,21 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_INVOKE_MATCHING_HPP_INCLUDED -#define BOOST_NUMPY_INVOKE_MATCHING_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_invoke_matching_hpp_ +#define boost_python_numpy_invoke_matching_hpp_ /** - * @file boost/numpy/invoke_matching.hpp * @brief Template invocation based on dtype matching. */ -#include -#include - +#include +#include #include -namespace boost -{ -namespace numpy -{ +namespace boost { namespace python { namespace numpy { namespace detail { @@ -119,7 +116,7 @@ private: Function & m_func; }; -} // namespace boost::numpy::detail +} // namespace boost::python::numpy::detail template void invoke_matching_nd(int nd, Function f) @@ -175,7 +172,7 @@ struct array_template_invoker_wrapper_1< DimSequence, boost::reference_wrapper(nd, func) {} }; -} // namespace boost::numpy::detail +} // namespace boost::python::numpy::detail template void invoke_matching_array(ndarray const & array_, Function f) @@ -184,7 +181,6 @@ void invoke_matching_array(ndarray const & array_, Function f) invoke_matching_dtype(array_.get_dtype(), wrapper); } -} // namespace boost::numpy -} // namespace boost +}}} // namespace boost::python::numpy -#endif // !BOOST_NUMPY_INVOKE_MATCHING_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/matrix.hpp b/include/boost/python/numpy/matrix.hpp index ff165f81..af20e8f9 100644 --- a/include/boost/python/numpy/matrix.hpp +++ b/include/boost/python/numpy/matrix.hpp @@ -1,23 +1,21 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_MATRIX_HPP_INCLUDED -#define BOOST_NUMPY_MATRIX_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_matrix_hpp_ +#define boost_python_numpy_matrix_hpp_ /** - * @file boost/numpy/matrix.hpp * @brief Object manager for numpy.matrix. */ #include -#include -#include +#include +#include -namespace boost -{ -namespace numpy -{ +namespace boost { namespace python { namespace numpy { /** * @brief A boost.python "object manager" (subclass of object) for numpy.matrix. @@ -31,19 +29,19 @@ namespace numpy */ class matrix : public ndarray { - static python::object construct(object_cref obj, dtype const & dt, bool copy); - static python::object construct(object_cref obj, bool copy); + static object construct(object_cref obj, dtype const & dt, bool copy); + static object construct(object_cref obj, bool copy); public: BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(matrix, ndarray); /// @brief Equivalent to "numpy.matrix(obj,dt,copy)" in Python. - explicit matrix(python::object const & obj, dtype const & dt, bool copy=true) - : ndarray(python::extract(construct(obj, dt, copy))) {} + explicit matrix(object const & obj, dtype const & dt, bool copy=true) + : ndarray(extract(construct(obj, dt, copy))) {} /// @brief Equivalent to "numpy.matrix(obj,copy=copy)" in Python. - explicit matrix(python::object const & obj, bool copy=true) - : ndarray(python::extract(construct(obj, copy))) {} + explicit matrix(object const & obj, bool copy=true) + : ndarray(extract(construct(obj, copy))) {} /// \brief Return a view of the matrix with the given dtype. matrix view(dtype const & dt) const; @@ -60,26 +58,25 @@ public: * @brief CallPolicies that causes a function that returns a numpy.ndarray to * return a numpy.matrix instead. */ -template -struct as_matrix : Base { - static PyObject * postcall(PyObject *, PyObject * result) { - python::object a = python::object(python::handle<>(result)); - numpy::matrix m(a, false); - Py_INCREF(m.ptr()); - return m.ptr(); - } +template +struct as_matrix : Base +{ + static PyObject * postcall(PyObject *, PyObject * result) + { + object a = object(handle<>(result)); + numpy::matrix m(a, false); + Py_INCREF(m.ptr()); + return m.ptr(); + } }; -} // namespace boost::numpy -namespace python -{ +} // namespace boost::python::numpy + namespace converter { NUMPY_OBJECT_MANAGER_TRAITS(numpy::matrix); -} // namespace boost::python::converter -} // namespace boost::python -} // namespace boost +}}} // namespace boost::python::converter -#endif // !BOOST_NUMPY_MATRIX_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/ndarray.hpp b/include/boost/python/numpy/ndarray.hpp index a702df33..2985907b 100644 --- a/include/boost/python/numpy/ndarray.hpp +++ b/include/boost/python/numpy/ndarray.hpp @@ -1,27 +1,24 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_NDARRAY_HPP_INCLUDED -#define BOOST_NUMPY_NDARRAY_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_ndarray_hpp_ +#define boost_python_numpy_ndarray_hpp_ /** - * @file boost/numpy/ndarray.hpp * @brief Object manager and various utilities for numpy.ndarray. */ #include #include #include -#include -#include - +#include +#include #include -namespace boost -{ -namespace numpy -{ +namespace boost { namespace python { namespace numpy { /** * @brief A boost.python "object manager" (subclass of object) for numpy.ndarray. @@ -29,7 +26,7 @@ namespace numpy * @todo This could have a lot more functionality (like boost::python::numeric::array). * Right now all that exists is what was needed to move raw data between C++ and Python. */ -class ndarray : public python::object +class ndarray : public object { /** @@ -104,7 +101,7 @@ public: dtype get_dtype() const; /// @brief Return the object that owns the array's data, or None if the array owns its own data. - python::object get_base() const; + object get_base() const; /// @brief Set the object that owns the array's data. Use with care. void set_base(object const & base); @@ -136,7 +133,7 @@ public: * * @internal This is simply a call to PyArray_Return(); */ - python::object scalarize() const; + object scalarize() const; }; /** @@ -156,8 +153,8 @@ ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt); * * @todo This does't seem to handle ndarray subtypes the same way that "numpy.array" does in Python. */ -ndarray array(python::object const & obj); -ndarray array(python::object const & obj, dtype const & dt); +ndarray array(object const & obj); +ndarray array(object const & obj, dtype const & dt); namespace detail { @@ -166,7 +163,7 @@ ndarray from_data_impl(void * data, dtype const & dt, std::vector const & shape, std::vector const & strides, - python::object const & owner, + object const & owner, bool writeable); template @@ -174,7 +171,7 @@ ndarray from_data_impl(void * data, dtype const & dt, Container shape, Container strides, - python::object const & owner, + object const & owner, bool writeable, typename boost::enable_if< boost::is_integral >::type * enabled = NULL) { @@ -185,12 +182,12 @@ ndarray from_data_impl(void * data, ndarray from_data_impl(void * data, dtype const & dt, - python::object const & shape, - python::object const & strides, - python::object const & owner, + object const & shape, + object const & strides, + object const & owner, bool writeable); -} // namespace boost::numpy::detail +} // namespace boost::python::numpy::detail /** * @brief Construct a new ndarray object from a raw pointer. @@ -250,29 +247,29 @@ inline ndarray from_data(void const * data, * @param[in] nd_max Maximum number of dimensions. * @param[in] flags Bitwise OR of flags specifying additional requirements. */ -ndarray from_object(python::object const & obj, dtype const & dt, +ndarray from_object(object const & obj, dtype const & dt, int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); -inline ndarray from_object(python::object const & obj, dtype const & dt, +inline ndarray from_object(object const & obj, dtype const & dt, int nd, ndarray::bitflag flags=ndarray::NONE) { return from_object(obj, dt, nd, nd, flags); } -inline ndarray from_object(python::object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE) +inline ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE) { return from_object(obj, dt, 0, 0, flags); } -ndarray from_object(python::object const & obj, int nd_min, int nd_max, +ndarray from_object(object const & obj, int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE); -inline ndarray from_object(python::object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE) +inline ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE) { return from_object(obj, nd, nd, flags); } -inline ndarray from_object(python::object const & obj, ndarray::bitflag flags=ndarray::NONE) +inline ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE) { return from_object(obj, 0, 0, flags); } @@ -287,17 +284,13 @@ inline ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b) return ndarray::bitflag(int(a) & int(b)); } -} // namespace boost::numpy +} // namespace boost::python::numpy -namespace python -{ namespace converter { NUMPY_OBJECT_MANAGER_TRAITS(numpy::ndarray); -} // namespace boost::python::converter -} // namespace boost::python -} // namespace boost +}}} // namespace boost::python::converter -#endif // !BOOST_NUMPY_NDARRAY_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/numpy_object_mgr_traits.hpp b/include/boost/python/numpy/numpy_object_mgr_traits.hpp index c0bad69c..8f9f4440 100644 --- a/include/boost/python/numpy/numpy_object_mgr_traits.hpp +++ b/include/boost/python/numpy/numpy_object_mgr_traits.hpp @@ -1,12 +1,13 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_NUMPY_OBJECT_MGR_TRAITS_HPP_INCLUDED -#define BOOST_NUMPY_NUMPY_OBJECT_MGR_TRAITS_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_numpy_object_mgr_traits_hpp_ +#define boost_python_numpy_numpy_object_mgr_traits_hpp_ /** - * @file boost/numpy/numpy_object_mgr_traits.hpp * @brief Macro that specializes object_manager_traits by requiring a * source-file implementation of get_pytype(). */ @@ -31,5 +32,5 @@ struct object_manager_traits \ static PyTypeObject const * get_pytype(); \ } -#endif // !BOOST_NUMPY_NUMPY_OBJECT_MGR_TRAITS_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/scalars.hpp b/include/boost/python/numpy/scalars.hpp index b0bb4e09..0ba23c41 100644 --- a/include/boost/python/numpy/scalars.hpp +++ b/include/boost/python/numpy/scalars.hpp @@ -1,30 +1,28 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_SCALARS_HPP_INCLUDED -#define BOOST_NUMPY_SCALARS_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_scalars_hpp_ +#define boost_python_numpy_scalars_hpp_ /** - * @file boost/numpy/scalars.hpp * @brief Object managers for array scalars (currently only numpy.void is implemented). */ #include -#include -#include +#include +#include -namespace boost -{ -namespace numpy -{ +namespace boost { namespace python { namespace numpy { /** * @brief A boost.python "object manager" (subclass of object) for numpy.void. * * @todo This could have a lot more functionality. */ -class void_ : public python::object +class void_ : public object { static python::detail::new_reference convert(object_cref arg, bool align); public: @@ -50,15 +48,11 @@ public: }; -} // namespace boost::numpy +} // namespace boost::python::numpy -namespace python -{ namespace converter { NUMPY_OBJECT_MANAGER_TRAITS(numpy::void_); -} // namespace boost::python::converter -} // namespace boost::python -} // namespace boost +}}} // namespace boost::python::converter -#endif // !BOOST_NUMPY_SCALARS_HPP_INCLUDED +#endif diff --git a/include/boost/python/numpy/ufunc.hpp b/include/boost/python/numpy/ufunc.hpp index d86fa34b..9262b378 100644 --- a/include/boost/python/numpy/ufunc.hpp +++ b/include/boost/python/numpy/ufunc.hpp @@ -1,24 +1,22 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NUMPY_UFUNC_HPP_INCLUDED -#define BOOST_NUMPY_UFUNC_HPP_INCLUDED +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_ufunc_hpp_ +#define boost_python_numpy_ufunc_hpp_ /** - * @file boost/numpy/ufunc.hpp * @brief Utilities to create ufunc-like broadcasting functions out of C++ functors. */ #include -#include -#include -#include +#include +#include +#include -namespace boost -{ -namespace numpy -{ +namespace boost { namespace python { namespace numpy { /** * @brief A boost.python "object manager" (subclass of object) for PyArray_MultiIter. @@ -36,11 +34,11 @@ namespace numpy * It's more dangerous than most object managers, however - maybe it actually belongs in * a detail namespace? */ -class multi_iter : public python::object +class multi_iter : public object { public: - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(multi_iter, python::object); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(multi_iter, object); /// @brief Increment the iterator. void next(); @@ -63,13 +61,13 @@ public: }; /// @brief Construct a multi_iter over a single sequence or scalar object. -multi_iter make_multi_iter(python::object const & a1); +multi_iter make_multi_iter(object const & a1); /// @brief Construct a multi_iter by broadcasting two objects. -multi_iter make_multi_iter(python::object const & a1, python::object const & a2); +multi_iter make_multi_iter(object const & a1, object const & a2); /// @brief Construct a multi_iter by broadcasting three objects. -multi_iter make_multi_iter(python::object const & a1, python::object const & a2, python::object const & a3); +multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3); /** * @brief Helps wrap a C++ functor taking a single scalar argument as a broadcasting ufunc-like @@ -102,12 +100,12 @@ struct unary_ufunc * @brief A C++ function with object arguments that broadcasts its arguments before * passing them to the underlying C++ functor. */ - static python::object call(TUnaryFunctor & self, python::object const & input, python::object const & output) + static object call(TUnaryFunctor & self, object const & input, object const & output) { dtype in_dtype = dtype::get_builtin(); dtype out_dtype = dtype::get_builtin(); ndarray in_array = from_object(input, in_dtype, ndarray::ALIGNED); - ndarray out_array = (output != python::object()) ? + ndarray out_array = (output != object()) ? from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE) : zeros(in_array.get_nd(), in_array.get_shape(), out_dtype); multi_iter iter = make_multi_iter(in_array, out_array); @@ -127,10 +125,9 @@ struct unary_ufunc * Users will often want to specify their own keyword names with the same signature, but this * is a convenient shortcut. */ - static python::object make() + static object make() { - namespace p = python; - return p::make_function(call, p::default_call_policies(), (p::arg("input"), p::arg("output")=p::object())); + return make_function(call, default_call_policies(), (arg("input"), arg("output")=object())); } }; @@ -163,9 +160,9 @@ template (); dtype in2_dtype = dtype::get_builtin(); @@ -173,7 +170,7 @@ struct binary_ufunc ndarray in1_array = from_object(input1, in1_dtype, ndarray::ALIGNED); ndarray in2_array = from_object(input2, in2_dtype, ndarray::ALIGNED); multi_iter iter = make_multi_iter(in1_array, in2_array); - ndarray out_array = (output != python::object()) + ndarray out_array = (output != object()) ? from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE) : zeros(iter.get_nd(), iter.get_shape(), out_dtype); iter = make_multi_iter(in1_array, in2_array, out_array); @@ -188,26 +185,21 @@ struct binary_ufunc return out_array.scalarize(); } - static python::object make() + static object make() { - namespace p = python; - return p::make_function(call, p::default_call_policies(), - (p::arg("input1"), p::arg("input2"), p::arg("output")=p::object())); + return make_function(call, default_call_policies(), + (arg("input1"), arg("input2"), arg("output")=object())); } }; -} // namespace boost::numpy +} // namespace boost::python::numpy -namespace python -{ namespace converter { NUMPY_OBJECT_MANAGER_TRAITS(numpy::multi_iter); -} // namespace boost::python::converter -} // namespace boost::python -} // namespace boost +}}} // namespace boost::python::converter -#endif // !BOOST_NUMPY_UFUNC_HPP_INCLUDED +#endif diff --git a/src/SConscript b/src/SConscript index a1d3de6b..6d81a9dc 100644 --- a/src/SConscript +++ b/src/SConscript @@ -42,3 +42,13 @@ env.BoostLibrary( 'import.cpp', 'exec.cpp', 'object/function_doc_signature.cpp']) + +if env['NUMPY']: + env.BoostLibrary( + 'numpy', + ['numpy/dtype.cpp', + 'numpy/matrix.cpp', + 'numpy/ndarray.cpp', + 'numpy/numpy.cpp', + 'numpy/scalars.cpp', + 'numpy/ufunc.cpp']) diff --git a/src/numpy/dtype.cpp b/src/numpy/dtype.cpp index 51fc9165..13904ddd 100644 --- a/src/numpy/dtype.cpp +++ b/src/numpy/dtype.cpp @@ -1,12 +1,14 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + #ifdef _MSC_VER #include #endif -#define BOOST_NUMPY_INTERNAL -#include +#define BOOST_PYTHON_NUMPY_INTERNAL +#include #define DTYPE_FROM_CODE(code) \ dtype(python::detail::new_reference(reinterpret_cast(PyArray_DescrFromType(code)))) @@ -35,10 +37,9 @@ namespace boost { namespace python { namespace converter { NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArrayDescr_Type, numpy::dtype) -}}} // namespace boost::python::converter - -namespace boost { namespace numpy { +} // namespace boost::python::converter +namespace numpy { namespace detail { dtype builtin_dtype::get() { return DTYPE_FROM_CODE(NPY_BOOL); } @@ -75,14 +76,18 @@ template dtype get_complex_dtype< 2 * NPY_BITSOF_LONGDOUBLE >(); } // namespace detail -python::detail::new_reference dtype::convert(python::object const & arg, bool align) { +python::detail::new_reference dtype::convert(object const & arg, bool align) +{ PyArray_Descr* obj=NULL; - if (align) { + if (align) + { if (PyArray_DescrAlignConverter(arg.ptr(), &obj) < 0) - python::throw_error_already_set(); - } else { + throw_error_already_set(); + } + else + { if (PyArray_DescrConverter(arg.ptr(), &obj) < 0) - python::throw_error_already_set(); + throw_error_already_set(); } return python::detail::new_reference(reinterpret_cast(obj)); } @@ -118,58 +123,68 @@ bool equivalent(dtype const & a, dtype const & b) { #endif } -namespace { +namespace +{ namespace pyconv = boost::python::converter; template -class array_scalar_converter { +class array_scalar_converter +{ public: - static PyTypeObject const * get_pytype() { - // This implementation depends on the fact that get_builtin returns pointers to objects - // NumPy has declared statically, and that the typeobj member also refers to a static - // object. That means we don't need to do any reference counting. - // In fact, I'm somewhat concerned that increasing the reference count of any of these - // might cause leaks, because I don't think Boost.Python ever decrements it, but it's - // probably a moot point if everything is actually static. - return reinterpret_cast(dtype::get_builtin().ptr())->typeobj; + static PyTypeObject const * get_pytype() + { + // This implementation depends on the fact that get_builtin returns pointers to objects + // NumPy has declared statically, and that the typeobj member also refers to a static + // object. That means we don't need to do any reference counting. + // In fact, I'm somewhat concerned that increasing the reference count of any of these + // might cause leaks, because I don't think Boost.Python ever decrements it, but it's + // probably a moot point if everything is actually static. + return reinterpret_cast(dtype::get_builtin().ptr())->typeobj; } - static void * convertible(PyObject * obj) { - if (obj->ob_type == get_pytype()) { - return obj; - } else { - dtype dt(python::detail::borrowed_reference(obj->ob_type)); - if (equivalent(dt, dtype::get_builtin())) { - return obj; - } - } + static void * convertible(PyObject * obj) + { + if (obj->ob_type == get_pytype()) + { + return obj; + } + else + { + dtype dt(python::detail::borrowed_reference(obj->ob_type)); + if (equivalent(dt, dtype::get_builtin())) + { + return obj; + } + } return 0; } - static void convert(PyObject * obj, pyconv::rvalue_from_python_stage1_data* data) { - void * storage = reinterpret_cast*>(data)->storage.bytes; - // We assume std::complex is a "standard layout" here and elsewhere; not guaranteed by - // C++03 standard, but true in every known implementation (and guaranteed by C++11). - PyArray_ScalarAsCtype(obj, reinterpret_cast(storage)); - data->convertible = storage; + static void convert(PyObject * obj, pyconv::rvalue_from_python_stage1_data* data) + { + void * storage = reinterpret_cast*>(data)->storage.bytes; + // We assume std::complex is a "standard layout" here and elsewhere; not guaranteed by + // C++03 standard, but true in every known implementation (and guaranteed by C++11). + PyArray_ScalarAsCtype(obj, reinterpret_cast(storage)); + data->convertible = storage; } - static void declare() { - pyconv::registry::push_back( - &convertible, &convert, python::type_id() + static void declare() + { + pyconv::registry::push_back(&convertible, &convert, python::type_id() #ifndef BOOST_PYTHON_NO_PY_SIGNATURES - , &get_pytype + , &get_pytype #endif - ); + ); } }; } // anonymous -void dtype::register_scalar_converters() { +void dtype::register_scalar_converters() +{ array_scalar_converter::declare(); array_scalar_converter::declare(); array_scalar_converter::declare(); @@ -196,5 +211,4 @@ void dtype::register_scalar_converters() { #endif } -} // namespace boost::numpy -} // namespace boost +}}} // namespace boost::python::numpy diff --git a/src/numpy/matrix.cpp b/src/numpy/matrix.cpp index 57e1e421..47d22616 100644 --- a/src/numpy/matrix.cpp +++ b/src/numpy/matrix.cpp @@ -1,28 +1,25 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_NUMPY_INTERNAL -#include -#include +#define BOOST_PYTHON_NUMPY_INTERNAL +#include +#include -namespace boost +namespace boost { namespace python { namespace numpy { -namespace numpy -{ namespace detail { -inline python::object get_matrix_type() +inline object get_matrix_type() { - python::object module = python::import("numpy"); + object module = import("numpy"); return module.attr("matrix"); } -} // namespace boost::numpy::detail -} // namespace boost::numpy +} // namespace boost::python::numpy::detail +} // namespace boost::python::numpy -namespace python -{ namespace converter { @@ -32,17 +29,16 @@ PyTypeObject const * object_manager_traits::get_pytype() } } // namespace boost::python::converter -} // namespace boost::python namespace numpy { -python::object matrix::construct(python::object const & obj, dtype const & dt, bool copy) +object matrix::construct(object const & obj, dtype const & dt, bool copy) { return numpy::detail::get_matrix_type()(obj, dt, copy); } -python::object matrix::construct(python::object const & obj, bool copy) +object matrix::construct(object const & obj, bool copy) { return numpy::detail::get_matrix_type()(obj, object(), copy); } @@ -61,8 +57,7 @@ matrix matrix::copy() const matrix matrix::transpose() const { - return matrix(python::extract(ndarray::transpose())); + return matrix(extract(ndarray::transpose())); } -} // namespace boost::numpy -} // namespace boost +}}} // namespace boost::python::numpy diff --git a/src/numpy/ndarray.cpp b/src/numpy/ndarray.cpp index 481692e3..710e3d49 100644 --- a/src/numpy/ndarray.cpp +++ b/src/numpy/ndarray.cpp @@ -1,21 +1,18 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_NUMPY_INTERNAL -#include +#define BOOST_PYTHON_NUMPY_INTERNAL +#include #include -namespace boost -{ -namespace python -{ +namespace boost { namespace python { namespace converter { NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArray_Type, numpy::ndarray) } // namespace boost::python::converter -} // namespace boost::python namespace numpy { @@ -277,5 +274,4 @@ ndarray from_object(python::object const & obj, int nd_min, int nd_max, ndarray: NULL))); } -} -} +}}} // namespace boost::python::numpy diff --git a/src/numpy/numpy.cpp b/src/numpy/numpy.cpp index 0cc3f5f6..8e259bc7 100644 --- a/src/numpy/numpy.cpp +++ b/src/numpy/numpy.cpp @@ -1,24 +1,24 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_NUMPY_INTERNAL_MAIN -#include -#include +#define BOOST_PYTHON_NUMPY_INTERNAL_MAIN +#include +#include -namespace boost -{ -namespace numpy -{ +namespace boost { namespace python { namespace numpy { #if PY_MAJOR_VERSION == 2 -static void wrap_import_array() { - import_array(); +static void wrap_import_array() +{ + import_array(); } #else -static void * wrap_import_array() { - import_array(); +static void * wrap_import_array() +{ + import_array(); } #endif @@ -30,5 +30,4 @@ void initialize(bool register_scalar_converters) dtype::register_scalar_converters(); } -} -} +}}} // namespace boost::python::numpy diff --git a/src/numpy/scalars.cpp b/src/numpy/scalars.cpp index 1f97df15..3947c06f 100644 --- a/src/numpy/scalars.cpp +++ b/src/numpy/scalars.cpp @@ -1,20 +1,17 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_NUMPY_INTERNAL -#include +#define BOOST_PYTHON_NUMPY_INTERNAL +#include -namespace boost -{ -namespace python -{ +namespace boost { namespace python { namespace converter { NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyVoidArrType_Type, numpy::void_) } // namespace boost::python::converter -} // namespace boost::python namespace numpy { @@ -36,5 +33,4 @@ void_ void_::copy() const (PyObject_CallMethod(this->ptr(), const_cast("copy"), const_cast("")))); } -} -} +}}} // namespace boost::python::numpy diff --git a/src/numpy/ufunc.cpp b/src/numpy/ufunc.cpp index a6a728f9..173d7213 100644 --- a/src/numpy/ufunc.cpp +++ b/src/numpy/ufunc.cpp @@ -1,36 +1,33 @@ // Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_NUMPY_INTERNAL -#include -#include +#define BOOST_PYTHON_NUMPY_INTERNAL +#include +#include -namespace boost -{ -namespace python -{ +namespace boost { namespace python { namespace converter { NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArrayMultiIter_Type, numpy::multi_iter) } // namespace boost::python::converter -} // namespace boost::python namespace numpy { -multi_iter make_multi_iter(python::object const & a1) +multi_iter make_multi_iter(object const & a1) { return multi_iter(python::detail::new_reference(PyArray_MultiIterNew(1, a1.ptr()))); } -multi_iter make_multi_iter(python::object const & a1, python::object const & a2) + multi_iter make_multi_iter(object const & a1, object const & a2) { return multi_iter(python::detail::new_reference(PyArray_MultiIterNew(2, a1.ptr(), a2.ptr()))); } -multi_iter make_multi_iter(python::object const & a1, python::object const & a2, python::object const & a3) +multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3) { return multi_iter(python::detail::new_reference(PyArray_MultiIterNew(3, a1.ptr(), a2.ptr(), a3.ptr()))); } @@ -65,5 +62,4 @@ Py_intptr_t multi_iter::shape(int n) const return reinterpret_cast(ptr())->dimensions[n]; } -} -} +}}} // namespace boost::python::numpy diff --git a/test/SConscript b/test/SConscript index c1ab335d..ee41547f 100644 --- a/test/SConscript +++ b/test/SConscript @@ -47,7 +47,6 @@ for test in [('injected',), ('minimal',), ('args',), ('raw_ctor',), - ('numpy',None, ['printer.py', 'numeric_tests.py', 'numarray_tests.py']), ('exception_translator',), ('test_enum', ['enum_ext']), ('test_cltree', ['cltree']), @@ -80,7 +79,7 @@ for test in [('injected',), ('extract',), ('crossmod_opaque', ['crossmod_opaque_a', 'crossmod_opaque_b']), ('opaque',), - ('voidptr',), +# ('voidptr',), ('pickle1',), ('pickle2',), ('pickle3',), @@ -145,5 +144,17 @@ if platform.system() == 'Windows': tests+=env.BPLTest('calling_conventions') tests+=env.BPLTest('calling_conventions_mf') +if env['NUMPY']: + numpy_env = env.Clone() + numpy_env.BoostUseLib('numpy') + for test in [('numpy/dtype',), + ('numpy/ufunc',), + ('numpy/templates',), + ('numpy/ndarray',), + ('numpy/indexing',), + ('numpy/shapes',),]: + tests+=numpy_env.BPLTest(*test) + + env.BoostTestSummary(tests) AlwaysBuild(tests) diff --git a/test/numpy/dtype_mod.cpp b/test/numpy/dtype.cpp similarity index 87% rename from test/numpy/dtype_mod.cpp rename to test/numpy/dtype.cpp index b9900590..3a011a25 100644 --- a/test/numpy/dtype_mod.cpp +++ b/test/numpy/dtype.cpp @@ -1,20 +1,21 @@ // Copyright Jim Bosch & Ankit Daftery 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include namespace p = boost::python; -namespace np = boost::numpy; +namespace np = boost::python::numpy; template np::dtype accept(T) { return np::dtype::get_builtin(); } -BOOST_PYTHON_MODULE(dtype_mod) +BOOST_PYTHON_MODULE(dtype_ext) { np::initialize(); // wrap dtype equivalence test, since it isn't available in Python API. diff --git a/test/numpy/dtype.py b/test/numpy/dtype.py index a280cc3a..021f756e 100644 --- a/test/numpy/dtype.py +++ b/test/numpy/dtype.py @@ -5,21 +5,21 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -import dtype_mod +import dtype_ext import unittest import numpy class DtypeTestCase(unittest.TestCase): def assertEquivalent(self, a, b): - return self.assert_(dtype_mod.equivalent(a, b), "%r is not equivalent to %r") + return self.assert_(dtype_ext.equivalent(a, b), "%r is not equivalent to %r") def testIntegers(self): for bits in (8, 16, 32, 64): s = getattr(numpy, "int%d" % bits) u = getattr(numpy, "uint%d" % bits) - fs = getattr(dtype_mod, "accept_int%d" % bits) - fu = getattr(dtype_mod, "accept_uint%d" % bits) + fs = getattr(dtype_ext, "accept_int%d" % bits) + fu = getattr(dtype_ext, "accept_uint%d" % bits) self.assertEquivalent(fs(s(1)), numpy.dtype(s)) self.assertEquivalent(fu(u(1)), numpy.dtype(u)) # these should just use the regular Boost.Python converters @@ -31,7 +31,7 @@ class DtypeTestCase(unittest.TestCase): self.assertEquivalent(fu(long(1)), numpy.dtype(u)) for name in ("bool_", "byte", "ubyte", "short", "ushort", "intc", "uintc"): t = getattr(numpy, name) - ft = getattr(dtype_mod, "accept_%s" % name) + ft = getattr(dtype_ext, "accept_%s" % name) self.assertEquivalent(ft(t(1)), numpy.dtype(t)) # these should just use the regular Boost.Python converters self.assertEquivalent(ft(True), numpy.dtype(t)) @@ -43,17 +43,17 @@ class DtypeTestCase(unittest.TestCase): def testFloats(self): f = numpy.float32 c = numpy.complex64 - self.assertEquivalent(dtype_mod.accept_float32(f(numpy.pi)), numpy.dtype(f)) - self.assertEquivalent(dtype_mod.accept_complex64(c(1+2j)), numpy.dtype(c)) + self.assertEquivalent(dtype_ext.accept_float32(f(numpy.pi)), numpy.dtype(f)) + self.assertEquivalent(dtype_ext.accept_complex64(c(1+2j)), numpy.dtype(c)) f = numpy.float64 c = numpy.complex128 - self.assertEquivalent(dtype_mod.accept_float64(f(numpy.pi)), numpy.dtype(f)) - self.assertEquivalent(dtype_mod.accept_complex128(c(1+2j)), numpy.dtype(c)) - if hasattr(numpy, "longdouble") and hasattr(dtype_mod, "accept_longdouble"): + self.assertEquivalent(dtype_ext.accept_float64(f(numpy.pi)), numpy.dtype(f)) + self.assertEquivalent(dtype_ext.accept_complex128(c(1+2j)), numpy.dtype(c)) + if hasattr(numpy, "longdouble") and hasattr(dtype_ext, "accept_longdouble"): f = numpy.longdouble c = numpy.clongdouble - self.assertEquivalent(dtype_mod.accept_longdouble(f(numpy.pi)), numpy.dtype(f)) - self.assertEquivalent(dtype_mod.accept_clongdouble(c(1+2j)), numpy.dtype(c)) + self.assertEquivalent(dtype_ext.accept_longdouble(f(numpy.pi)), numpy.dtype(f)) + self.assertEquivalent(dtype_ext.accept_clongdouble(c(1+2j)), numpy.dtype(c)) if __name__=="__main__": diff --git a/test/numpy/indexing_mod.cpp b/test/numpy/indexing.cpp similarity index 77% rename from test/numpy/indexing_mod.cpp rename to test/numpy/indexing.cpp index dadb05de..f3cc4571 100644 --- a/test/numpy/indexing_mod.cpp +++ b/test/numpy/indexing.cpp @@ -1,13 +1,14 @@ // Copyright Jim Bosch & Ankit Daftery 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include namespace p = boost::python; -namespace np = boost::numpy; +namespace np = boost::python::numpy; p::object single(np::ndarray ndarr, int i) { return ndarr[i];} p::object slice(np::ndarray ndarr, p::slice sl) { return ndarr[sl];} @@ -15,7 +16,7 @@ p::object indexarray(np::ndarray ndarr, np::ndarray d1) { return ndarr[d1];} p::object indexarray_2d(np::ndarray ndarr, np::ndarray d1,np::ndarray d2) { return ndarr[p::make_tuple(d1,d2)];} p::object indexslice(np::ndarray ndarr, np::ndarray d1, p::slice sl) { return ndarr[p::make_tuple(d1, sl)];} -BOOST_PYTHON_MODULE(indexing_mod) +BOOST_PYTHON_MODULE(indexing_ext) { np::initialize(); p::def("single", single); diff --git a/test/numpy/indexing.py b/test/numpy/indexing.py index e3d06a22..ebd9dcba 100644 --- a/test/numpy/indexing.py +++ b/test/numpy/indexing.py @@ -7,49 +7,49 @@ import unittest import numpy -import indexing_mod +import indexing_ext class TestIndexing(unittest.TestCase): def testSingle(self): x = numpy.arange(0,10) for i in range(0,10): - numpy.testing.assert_equal(indexing_mod.single(x,i), i) + numpy.testing.assert_equal(indexing_ext.single(x,i), i) for i in range(-10,0): - numpy.testing.assert_equal(indexing_mod.single(x,i),10+i) + numpy.testing.assert_equal(indexing_ext.single(x,i),10+i) def testSlice(self): x = numpy.arange(0,10) sl = slice(3,8) b = [3,4,5,6,7] - numpy.testing.assert_equal(indexing_mod.slice(x,sl), b) + numpy.testing.assert_equal(indexing_ext.slice(x,sl), b) def testStepSlice(self): x = numpy.arange(0,10) sl = slice(3,8,2) b = [3,5,7] - numpy.testing.assert_equal(indexing_mod.slice(x,sl), b) + numpy.testing.assert_equal(indexing_ext.slice(x,sl), b) def testIndex(self): x = numpy.arange(0,10) chk = numpy.array([3,4,5,6]) - numpy.testing.assert_equal(indexing_mod.indexarray(x,chk),chk) + numpy.testing.assert_equal(indexing_ext.indexarray(x,chk),chk) chk = numpy.array([[0,1],[2,3]]) - numpy.testing.assert_equal(indexing_mod.indexarray(x,chk),chk) + numpy.testing.assert_equal(indexing_ext.indexarray(x,chk),chk) x = numpy.arange(9).reshape(3,3) y = numpy.array([0,1]) z = numpy.array([0,2]) chk = numpy.array([0,5]) - numpy.testing.assert_equal(indexing_mod.indexarray(x,y,z),chk) + numpy.testing.assert_equal(indexing_ext.indexarray(x,y,z),chk) x = numpy.arange(0,10) b = x>4 chk = numpy.array([5,6,7,8,9]) - numpy.testing.assert_equal(indexing_mod.indexarray(x,b),chk) + numpy.testing.assert_equal(indexing_ext.indexarray(x,b),chk) x = numpy.arange(9).reshape(3,3) b = numpy.array([0,2]) sl = slice(0,3) chk = numpy.array([[0,1,2],[6,7,8]]) - numpy.testing.assert_equal(indexing_mod.indexslice(x,b,sl),chk) + numpy.testing.assert_equal(indexing_ext.indexslice(x,b,sl),chk) if __name__=="__main__": unittest.main() diff --git a/test/numpy/ndarray_mod.cpp b/test/numpy/ndarray.cpp similarity index 88% rename from test/numpy/ndarray_mod.cpp rename to test/numpy/ndarray.cpp index 099b005a..808872e8 100644 --- a/test/numpy/ndarray_mod.cpp +++ b/test/numpy/ndarray.cpp @@ -1,19 +1,20 @@ // Copyright Jim Bosch & Ankit Daftery 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace p = boost::python; -namespace np = boost::numpy; +namespace np = boost::python::numpy; np::ndarray zeros(p::tuple shape, np::dtype dt) { return np::zeros(shape, dt);} np::ndarray array2(p::object obj, np::dtype dt) { return np::array(obj,dt);} np::ndarray array1(p::object obj) { return np::array(obj);} np::ndarray empty1(p::tuple shape, np::dtype dt) { return np::empty(shape,dt);} -np::ndarray c_empty(p::tuple shape, np::dtype dt) +np::ndarray c_empty(p::tuple shape, np::dtype dt) { // convert 'shape' to a C array so we can test the corresponding // version of the constructor @@ -30,7 +31,7 @@ np::ndarray transpose(np::ndarray arr) { return arr.transpose();} np::ndarray squeeze(np::ndarray arr) { return arr.squeeze();} np::ndarray reshape(np::ndarray arr,p::tuple tup) { return arr.reshape(tup);} -BOOST_PYTHON_MODULE(ndarray_mod) +BOOST_PYTHON_MODULE(ndarray_ext) { np::initialize(); p::def("zeros", zeros); diff --git a/test/numpy/ndarray.py b/test/numpy/ndarray.py index 6ef387ea..fb92a2a2 100644 --- a/test/numpy/ndarray.py +++ b/test/numpy/ndarray.py @@ -5,7 +5,7 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -import ndarray_mod +import ndarray_ext import unittest import numpy @@ -16,7 +16,7 @@ class TestNdarray(unittest.TestCase): v = numpy.zeros(60, dtype=dtp) dt = numpy.dtype(dtp) for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)): - a1 = ndarray_mod.zeros(shape,dt) + a1 = ndarray_ext.zeros(shape,dt) a2 = v.reshape(a1.shape) self.assertEqual(shape,a1.shape) self.assert_((a1 == a2).all()) @@ -25,7 +25,7 @@ class TestNdarray(unittest.TestCase): for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128): dt = numpy.dtype(dtp) shape = (6, 10) - a1 = ndarray_mod.zeros_matrix(shape, dt) + a1 = ndarray_ext.zeros_matrix(shape, dt) a2 = numpy.matrix(numpy.zeros(shape, dtype=dtp)) self.assertEqual(shape,a1.shape) self.assert_((a1 == a2).all()) @@ -36,8 +36,8 @@ class TestNdarray(unittest.TestCase): for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128): v = numpy.array(a, dtype=dtp) dt = numpy.dtype(dtp) - a1 = ndarray_mod.array(a) - a2 = ndarray_mod.array(a,dt) + a1 = ndarray_ext.array(a) + a2 = ndarray_ext.array(a,dt) self.assert_((a1 == v).all()) self.assert_((a2 == v).all()) for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)): @@ -50,8 +50,8 @@ class TestNdarray(unittest.TestCase): for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128): dt = numpy.dtype(dtp) for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)): - a1 = ndarray_mod.empty(shape,dt) - a2 = ndarray_mod.c_empty(shape,dt) + a1 = ndarray_ext.empty(shape,dt) + a2 = ndarray_ext.c_empty(shape,dt) self.assertEqual(shape,a1.shape) self.assertEqual(shape,a2.shape) @@ -61,18 +61,18 @@ class TestNdarray(unittest.TestCase): for shape in ((6,10),(4,3,5),(2,2,3,5)): a1 = numpy.empty(shape,dt) a2 = a1.transpose() - a1 = ndarray_mod.transpose(a1) + a1 = ndarray_ext.transpose(a1) self.assertEqual(a1.shape,a2.shape) def testSqueeze(self): a1 = numpy.array([[[3,4,5]]]) a2 = a1.squeeze() - a1 = ndarray_mod.squeeze(a1) + a1 = ndarray_ext.squeeze(a1) self.assertEqual(a1.shape,a2.shape) def testReshape(self): a1 = numpy.empty((2,2)) - a2 = ndarray_mod.reshape(a1,(1,4)) + a2 = ndarray_ext.reshape(a1,(1,4)) self.assertEqual(a2.shape,(1,4)) if __name__=="__main__": diff --git a/test/numpy/shapes_mod.cpp b/test/numpy/shapes.cpp similarity index 59% rename from test/numpy/shapes_mod.cpp rename to test/numpy/shapes.cpp index f03425ae..a245df15 100644 --- a/test/numpy/shapes_mod.cpp +++ b/test/numpy/shapes.cpp @@ -1,12 +1,13 @@ // Copyright Jim Bosch & Ankit Daftery 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace p = boost::python; -namespace np = boost::numpy; +namespace np = boost::python::numpy; np::ndarray reshape(np::ndarray old_array, p::tuple shape) { @@ -14,7 +15,7 @@ np::ndarray reshape(np::ndarray old_array, p::tuple shape) return local_shape; } -BOOST_PYTHON_MODULE(shapes_mod) +BOOST_PYTHON_MODULE(shapes_ext) { np::initialize(); p::def("reshape", reshape); diff --git a/test/numpy/shapes.py b/test/numpy/shapes.py index 76c0e901..d0a0099c 100644 --- a/test/numpy/shapes.py +++ b/test/numpy/shapes.py @@ -5,7 +5,7 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -import shapes_mod +import shapes_ext import unittest import numpy @@ -14,7 +14,7 @@ class TestShapes(unittest.TestCase): def testShapes(self): a1 = numpy.array([(0,1),(2,3)]) a1_shape = (1,4) - a1 = shapes_mod.reshape(a1,a1_shape) + a1 = shapes_ext.reshape(a1,a1_shape) self.assertEqual(a1_shape,a1.shape) if __name__=="__main__": diff --git a/test/numpy/templates_mod.cpp b/test/numpy/templates.cpp similarity index 73% rename from test/numpy/templates_mod.cpp rename to test/numpy/templates.cpp index c9a4cc91..83de6bd2 100644 --- a/test/numpy/templates_mod.cpp +++ b/test/numpy/templates.cpp @@ -1,16 +1,17 @@ // Copyright Jim Bosch & Ankit Daftery 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #include namespace p = boost::python; -namespace np = boost::numpy; +namespace np = boost::python::numpy; -struct ArrayFiller +struct ArrayFiller { typedef boost::mpl::vector< short, int, float, std::complex > TypeSequence; @@ -19,14 +20,14 @@ struct ArrayFiller explicit ArrayFiller(np::ndarray const & arg) : argument(arg) {} template - void apply() const + void apply() const { - if (N == 1) + if (N == 1) { char * p = argument.get_data(); int stride = argument.strides(0); int size = argument.shape(0); - for (int n = 0; n != size; ++n, p += stride) + for (int n = 0; n != size; ++n, p += stride) *reinterpret_cast(p) = static_cast(n); } else @@ -37,7 +38,7 @@ struct ArrayFiller int rows = argument.shape(0); int cols = argument.shape(1); int i = 0; - for (int n = 0; n != rows; ++n, row_p += row_stride) + for (int n = 0; n != rows; ++n, row_p += row_stride) { char * col_p = row_p; for (int m = 0; m != cols; ++i, ++m, col_p += col_stride) @@ -49,13 +50,13 @@ struct ArrayFiller np::ndarray argument; }; -void fill(np::ndarray const & arg) +void fill(np::ndarray const & arg) { ArrayFiller filler(arg); np::invoke_matching_array(arg, filler); } -BOOST_PYTHON_MODULE(templates_mod) +BOOST_PYTHON_MODULE(templates_ext) { np::initialize(); p::def("fill", fill); diff --git a/test/numpy/templates.py b/test/numpy/templates.py index 09e90fbe..8290b13a 100755 --- a/test/numpy/templates.py +++ b/test/numpy/templates.py @@ -5,7 +5,7 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -import templates_mod +import templates_ext import unittest import numpy @@ -17,12 +17,12 @@ class TestTemplates(unittest.TestCase): for shape in ((12,), (4, 3), (2, 6)): a1 = numpy.zeros(shape, dtype=dtype) a2 = v.reshape(a1.shape) - templates_mod.fill(a1) + templates_ext.fill(a1) self.assert_((a1 == a2).all()) a1 = numpy.zeros((12,), dtype=numpy.float64) - self.assertRaises(TypeError, templates_mod.fill, a1) + self.assertRaises(TypeError, templates_ext.fill, a1) a1 = numpy.zeros((12,2,3), dtype=numpy.float32) - self.assertRaises(TypeError, templates_mod.fill, a1) + self.assertRaises(TypeError, templates_ext.fill, a1) if __name__=="__main__": unittest.main() diff --git a/test/numpy/ufunc_mod.cpp b/test/numpy/ufunc.cpp similarity index 71% rename from test/numpy/ufunc_mod.cpp rename to test/numpy/ufunc.cpp index cfad1088..3a9d43cb 100644 --- a/test/numpy/ufunc_mod.cpp +++ b/test/numpy/ufunc.cpp @@ -1,14 +1,15 @@ // Copyright Jim Bosch & Ankit Daftery 2010-2012. +// Copyright Stefan Seefeld 2016. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace p = boost::python; -namespace np = boost::numpy; +namespace np = boost::python::numpy; -struct UnaryCallable +struct UnaryCallable { typedef double argument_type; typedef double result_type; @@ -16,7 +17,7 @@ struct UnaryCallable double operator()(double r) const { return r * 2;} }; -struct BinaryCallable +struct BinaryCallable { typedef double first_argument_type; typedef double second_argument_type; @@ -25,7 +26,7 @@ struct BinaryCallable double operator()(double a, double b) const { return a * 2 + b * 3;} }; -BOOST_PYTHON_MODULE(ufunc_mod) +BOOST_PYTHON_MODULE(ufunc_ext) { np::initialize(); p::class_("UnaryCallable") diff --git a/test/numpy/ufunc.py b/test/numpy/ufunc.py index b698082c..e820121e 100755 --- a/test/numpy/ufunc.py +++ b/test/numpy/ufunc.py @@ -5,7 +5,7 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -import ufunc_mod +import ufunc_ext import unittest import numpy from numpy.testing.utils import assert_array_almost_equal @@ -13,12 +13,12 @@ from numpy.testing.utils import assert_array_almost_equal class TestUnary(unittest.TestCase): def testScalar(self): - f = ufunc_mod.UnaryCallable() + f = ufunc_ext.UnaryCallable() assert_array_almost_equal(f(1.0), 2.0) assert_array_almost_equal(f(3.0), 6.0) def testArray(self): - f = ufunc_mod.UnaryCallable() + f = ufunc_ext.UnaryCallable() a = numpy.arange(5, dtype=float) b = f(a) assert_array_almost_equal(b, a*2.0) @@ -28,7 +28,7 @@ class TestUnary(unittest.TestCase): assert_array_almost_equal(d, a*2.0) def testList(self): - f = ufunc_mod.UnaryCallable() + f = ufunc_ext.UnaryCallable() a = range(5) b = f(a) assert_array_almost_equal(b/2.0, a) @@ -36,12 +36,12 @@ class TestUnary(unittest.TestCase): class TestBinary(unittest.TestCase): def testScalar(self): - f = ufunc_mod.BinaryCallable() + f = ufunc_ext.BinaryCallable() assert_array_almost_equal(f(1.0, 3.0), 11.0) assert_array_almost_equal(f(3.0, 2.0), 12.0) def testArray(self): - f = ufunc_mod.BinaryCallable() + f = ufunc_ext.BinaryCallable() a = numpy.random.randn(5) b = numpy.random.randn(5) assert_array_almost_equal(f(a,b), (a*2+b*3))