mirror of
https://github.com/boostorg/python.git
synced 2026-01-28 07:22:31 +00:00
Adjust NumPy code to work with new directory / namespace structure.
This commit is contained in:
13
.travis.yml
13
.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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
86
config/numpy.py
Normal file
86
config/numpy.py
Normal file
@@ -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
|
||||
@@ -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)
|
||||
|
||||
592
config/tools/sphinx4scons.py
Normal file
592
config/tools/sphinx4scons.py
Normal file
@@ -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
|
||||
@@ -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/')
|
||||
|
||||
BIN
doc/numpy/_static/bpl.png
Normal file
BIN
doc/numpy/_static/bpl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@@ -86,12 +86,12 @@
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="{{ pathto('index') }}"><img height="86" width="277"
|
||||
<h3><a href="{{ pathto('index') }}"><img
|
||||
alt="C++ Boost" src="{{ pathto('_static/' + logo, 1) }}" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="{{ pathto('index') }}">Boost.NumPy</a></h1>
|
||||
<!-- <h1 align="center"><a href="{{ pathto('index') }}">Boost.NumPy</a></h1>-->
|
||||
<!-- <h2 align="center">CallPolicies Concept</h2>-->
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -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)
|
||||
]
|
||||
|
||||
@@ -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 <tutorial/index>
|
||||
Reference <reference/index>
|
||||
cmakeBuild.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
|
||||
|
||||
``<boost/numpy/ufunc.hpp>`` contains the ``binary_ufunc`` structure definitions
|
||||
``<boost/python/numpy/ufunc.hpp>`` 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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
``<boost/numpy/dtype.hpp>`` 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
|
||||
``<boost/python/numpy/dtype.hpp>`` 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<double>();
|
||||
p::tuple for_custom_dtype = p::make_tuple("ha",dtype);
|
||||
np::dtype custom_dtype = np::dtype(list_for_dtype);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Boost.NumPy Reference
|
||||
=====================
|
||||
Boost.Python NumPy extension Reference
|
||||
======================================
|
||||
|
||||
Contents:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
``<boost/numpy/ufunc.hpp>`` contains the class definitions for ``multi_iter``
|
||||
``<boost/python/numpy/ufunc.hpp>`` 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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
``<boost/numpy/ndarray.hpp>`` contains the structures and methods necessary to move raw data between C++ and Python and create ndarrays from the data
|
||||
``<boost/python/numpy/ndarray.hpp>`` 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 <typename Container>
|
||||
ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner);
|
||||
template <typename Container>
|
||||
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) ;
|
||||
|
||||
@@ -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
|
||||
|
||||
``<boost/numpy/ufunc.hpp>`` contains the ``unary_ufunc`` structure definitions
|
||||
``<boost/python/numpy/ufunc.hpp>`` 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 <typename TUnaryFunctor,
|
||||
typename TArgument=typename TUnaryFunctor::argument_type,
|
||||
typename TResult=typename TUnaryFunctor::result_type>
|
||||
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 <typename TUnaryFunctor,
|
||||
typename TArgument=typename TUnaryFunctor::argument_type,
|
||||
typename TResult=typename TUnaryFunctor::result_type>
|
||||
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
|
||||
{
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Boost.NumPy Tutorial
|
||||
====================
|
||||
Boost.Python NumPy extension Tutorial
|
||||
=====================================
|
||||
|
||||
Contents:
|
||||
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
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::
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ Lets try and see how we can use the binary and unary ufunc methods
|
||||
|
||||
After the neccessary includes ::
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
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 ::
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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 <boost/numpy/dtype.hpp>
|
||||
#include <boost/numpy/ndarray.hpp>
|
||||
#include <boost/numpy/scalars.hpp>
|
||||
#include <boost/numpy/matrix.hpp>
|
||||
#include <boost/numpy/ufunc.hpp>
|
||||
#include <boost/numpy/invoke_matching.hpp>
|
||||
#include <boost/python/numpy/dtype.hpp>
|
||||
#include <boost/python/numpy/ndarray.hpp>
|
||||
#include <boost/python/numpy/scalars.hpp>
|
||||
#include <boost/python/numpy/matrix.hpp>
|
||||
#include <boost/python/numpy/ufunc.hpp>
|
||||
#include <boost/python/numpy/invoke_matching.hpp>
|
||||
|
||||
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
|
||||
|
||||
@@ -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 <boost/python.hpp>
|
||||
#include <boost/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
|
||||
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
|
||||
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 <typename T>
|
||||
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<T>, false > {
|
||||
template <typename T>
|
||||
inline dtype dtype::get_builtin() { return detail::builtin_dtype<T>::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
|
||||
|
||||
@@ -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 <boost/python.hpp>
|
||||
#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 <numpy/arrayobject.h>
|
||||
#include <numpy/ufuncobject.h>
|
||||
#include <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
|
||||
#define NUMPY_OBJECT_MANAGER_TRAITS_IMPL(pytype,manager) \
|
||||
PyTypeObject const * object_manager_traits<manager>::get_pytype() { return &pytype; }
|
||||
|
||||
#endif // !BOOST_NUMPY_INTERNAL_HPP_INCLUDED
|
||||
#endif
|
||||
|
||||
@@ -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 <boost/numpy/dtype.hpp>
|
||||
#include <boost/numpy/ndarray.hpp>
|
||||
|
||||
#include <boost/python/numpy/dtype.hpp>
|
||||
#include <boost/python/numpy/ndarray.hpp>
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
|
||||
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 <typename Sequence, typename Function>
|
||||
void invoke_matching_nd(int nd, Function f)
|
||||
@@ -175,7 +172,7 @@ struct array_template_invoker_wrapper_1< DimSequence, boost::reference_wrapper<F
|
||||
: array_template_invoker_wrapper_1< DimSequence, Function >(nd, func) {}
|
||||
};
|
||||
|
||||
} // namespace boost::numpy::detail
|
||||
} // namespace boost::python::numpy::detail
|
||||
|
||||
template <typename TypeSequence, typename DimSequence, typename Function>
|
||||
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<TypeSequence>(array_.get_dtype(), wrapper);
|
||||
}
|
||||
|
||||
} // namespace boost::numpy
|
||||
} // namespace boost
|
||||
}}} // namespace boost::python::numpy
|
||||
|
||||
#endif // !BOOST_NUMPY_INVOKE_MATCHING_HPP_INCLUDED
|
||||
#endif
|
||||
|
||||
@@ -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 <boost/python.hpp>
|
||||
#include <boost/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/numpy/ndarray.hpp>
|
||||
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/python/numpy/ndarray.hpp>
|
||||
|
||||
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<ndarray>(construct(obj, dt, copy))) {}
|
||||
explicit matrix(object const & obj, dtype const & dt, bool copy=true)
|
||||
: ndarray(extract<ndarray>(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<ndarray>(construct(obj, copy))) {}
|
||||
explicit matrix(object const & obj, bool copy=true)
|
||||
: ndarray(extract<ndarray>(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 <typename Base = python::default_call_policies>
|
||||
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 <typename Base = default_call_policies>
|
||||
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
|
||||
|
||||
@@ -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 <boost/python.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/numpy/dtype.hpp>
|
||||
|
||||
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/python/numpy/dtype.hpp>
|
||||
#include <vector>
|
||||
|
||||
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<Py_intptr_t> const & shape,
|
||||
std::vector<Py_intptr_t> const & strides,
|
||||
python::object const & owner,
|
||||
object const & owner,
|
||||
bool writeable);
|
||||
|
||||
template <typename Container>
|
||||
@@ -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<typename Container::value_type> >::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
|
||||
|
||||
@@ -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<manager> \
|
||||
static PyTypeObject const * get_pytype(); \
|
||||
}
|
||||
|
||||
#endif // !BOOST_NUMPY_NUMPY_OBJECT_MGR_TRAITS_HPP_INCLUDED
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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 <boost/python.hpp>
|
||||
#include <boost/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/numpy/dtype.hpp>
|
||||
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/python/numpy/dtype.hpp>
|
||||
|
||||
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
|
||||
|
||||
@@ -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 <boost/python.hpp>
|
||||
#include <boost/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/numpy/dtype.hpp>
|
||||
#include <boost/numpy/ndarray.hpp>
|
||||
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
|
||||
#include <boost/python/numpy/dtype.hpp>
|
||||
#include <boost/python/numpy/ndarray.hpp>
|
||||
|
||||
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<TArgument>();
|
||||
dtype out_dtype = dtype::get_builtin<TResult>();
|
||||
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 <typename TBinaryFunctor,
|
||||
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)
|
||||
{
|
||||
dtype in1_dtype = dtype::get_builtin<TArgument1>();
|
||||
dtype in2_dtype = dtype::get_builtin<TArgument2>();
|
||||
@@ -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
|
||||
|
||||
@@ -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'])
|
||||
|
||||
@@ -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 <boost/cstdint.hpp>
|
||||
#endif
|
||||
#define BOOST_NUMPY_INTERNAL
|
||||
#include <boost/numpy/internal.hpp>
|
||||
#define BOOST_PYTHON_NUMPY_INTERNAL
|
||||
#include <boost/python/numpy/internal.hpp>
|
||||
|
||||
#define DTYPE_FROM_CODE(code) \
|
||||
dtype(python::detail::new_reference(reinterpret_cast<PyObject*>(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<bool,true>::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<PyObject*>(obj));
|
||||
}
|
||||
@@ -118,58 +123,68 @@ bool equivalent(dtype const & a, dtype const & b) {
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
|
||||
namespace pyconv = boost::python::converter;
|
||||
|
||||
template <typename T>
|
||||
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<PyArray_Descr*>(dtype::get_builtin<T>().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<PyArray_Descr*>(dtype::get_builtin<T>().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<T>())) {
|
||||
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<T>()))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void convert(PyObject * obj, pyconv::rvalue_from_python_stage1_data* data) {
|
||||
void * storage = reinterpret_cast<pyconv::rvalue_from_python_storage<T>*>(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<T*>(storage));
|
||||
data->convertible = storage;
|
||||
static void convert(PyObject * obj, pyconv::rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void * storage = reinterpret_cast<pyconv::rvalue_from_python_storage<T>*>(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<T*>(storage));
|
||||
data->convertible = storage;
|
||||
}
|
||||
|
||||
static void declare() {
|
||||
pyconv::registry::push_back(
|
||||
&convertible, &convert, python::type_id<T>()
|
||||
static void declare()
|
||||
{
|
||||
pyconv::registry::push_back(&convertible, &convert, python::type_id<T>()
|
||||
#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<bool>::declare();
|
||||
array_scalar_converter<npy_uint8>::declare();
|
||||
array_scalar_converter<npy_int8>::declare();
|
||||
@@ -196,5 +211,4 @@ void dtype::register_scalar_converters() {
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace boost::numpy
|
||||
} // namespace boost
|
||||
}}} // namespace boost::python::numpy
|
||||
|
||||
@@ -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 <boost/numpy/internal.hpp>
|
||||
#include <boost/numpy/matrix.hpp>
|
||||
#define BOOST_PYTHON_NUMPY_INTERNAL
|
||||
#include <boost/python/numpy/internal.hpp>
|
||||
#include <boost/python/numpy/matrix.hpp>
|
||||
|
||||
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<numpy::matrix>::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<matrix>(ndarray::transpose()));
|
||||
return matrix(extract<matrix>(ndarray::transpose()));
|
||||
}
|
||||
|
||||
} // namespace boost::numpy
|
||||
} // namespace boost
|
||||
}}} // namespace boost::python::numpy
|
||||
|
||||
@@ -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 <boost/numpy/internal.hpp>
|
||||
#define BOOST_PYTHON_NUMPY_INTERNAL
|
||||
#include <boost/python/numpy/internal.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
|
||||
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
|
||||
|
||||
@@ -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 <boost/numpy/internal.hpp>
|
||||
#include <boost/numpy/dtype.hpp>
|
||||
#define BOOST_PYTHON_NUMPY_INTERNAL_MAIN
|
||||
#include <boost/python/numpy/internal.hpp>
|
||||
#include <boost/python/numpy/dtype.hpp>
|
||||
|
||||
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
|
||||
|
||||
@@ -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 <boost/numpy/internal.hpp>
|
||||
#define BOOST_PYTHON_NUMPY_INTERNAL
|
||||
#include <boost/python/numpy/internal.hpp>
|
||||
|
||||
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<char*>("copy"), const_cast<char*>(""))));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}}} // namespace boost::python::numpy
|
||||
|
||||
@@ -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 <boost/numpy/internal.hpp>
|
||||
#include <boost/numpy/ufunc.hpp>
|
||||
#define BOOST_PYTHON_NUMPY_INTERNAL
|
||||
#include <boost/python/numpy/internal.hpp>
|
||||
#include <boost/python/numpy/ufunc.hpp>
|
||||
|
||||
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<PyArrayMultiIterObject*>(ptr())->dimensions[n];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}}} // namespace boost::python::numpy
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
template <typename T>
|
||||
np::dtype accept(T) {
|
||||
return np::dtype::get_builtin<T>();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(dtype_mod)
|
||||
BOOST_PYTHON_MODULE(dtype_ext)
|
||||
{
|
||||
np::initialize();
|
||||
// wrap dtype equivalence test, since it isn't available in Python API.
|
||||
@@ -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__":
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <boost/python/slice.hpp>
|
||||
|
||||
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);
|
||||
@@ -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()
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
|
||||
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);
|
||||
@@ -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__":
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
|
||||
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);
|
||||
@@ -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__":
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/vector_c.hpp>
|
||||
|
||||
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<double> > TypeSequence;
|
||||
@@ -19,14 +20,14 @@ struct ArrayFiller
|
||||
explicit ArrayFiller(np::ndarray const & arg) : argument(arg) {}
|
||||
|
||||
template <typename T, int N>
|
||||
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<T*>(p) = static_cast<T>(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<ArrayFiller::TypeSequence, ArrayFiller::DimSequence >(arg, filler);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(templates_mod)
|
||||
BOOST_PYTHON_MODULE(templates_ext)
|
||||
{
|
||||
np::initialize();
|
||||
p::def("fill", fill);
|
||||
@@ -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()
|
||||
|
||||
@@ -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 <boost/numpy.hpp>
|
||||
#include <boost/python/numpy.hpp>
|
||||
|
||||
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>("UnaryCallable")
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user