Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78456 - in sandbox/numpy: . boost boost/numpy libs/numpy/src libs/numpy/test
From: talljimbo_at_[hidden]
Date: 2012-05-13 13:46:48


Author: jbosch
Date: 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
New Revision: 78456
URL: http://svn.boost.org/trac/boost/changeset/78456

Log:
Merge changes from GitHub master in preparation for push to Boost Sandbox.
Added:
   sandbox/numpy/.gitignore (contents, props changed)
   sandbox/numpy/README (contents, props changed)
   sandbox/numpy/libs/numpy/test/dtype.py (contents, props changed)
   sandbox/numpy/libs/numpy/test/dtype_mod.cpp (contents, props changed)
Text files modified:
   sandbox/numpy/SConscript | 192 ++++++++++++++++++++-----------------
   sandbox/numpy/SConstruct | 16 ++
   sandbox/numpy/boost/numpy.hpp | 5
   sandbox/numpy/boost/numpy/dtype.hpp | 64 +++++++++--
   sandbox/numpy/boost/numpy/matrix.hpp | 14 ++
   sandbox/numpy/libs/numpy/src/dtype.cpp | 202 ++++++++++++++++++++++++---------------
   sandbox/numpy/libs/numpy/src/numpy.cpp | 5
   sandbox/numpy/libs/numpy/test/SConscript | 4
   sandbox/numpy/libs/numpy/test/indexing.py | 82 ++++++++-------
   sandbox/numpy/libs/numpy/test/ndarray.py | 122 +++++++++++++----------
   sandbox/numpy/libs/numpy/test/ndarray_mod.cpp | 2
   sandbox/numpy/libs/numpy/test/shapes.py | 16 +-
   sandbox/numpy/libs/numpy/test/templates.py | 2
   sandbox/numpy/libs/numpy/test/ufunc.py | 2
   sandbox/numpy/libs/numpy/test/ufunc_mod.cpp | 4
   15 files changed, 444 insertions(+), 288 deletions(-)

Added: sandbox/numpy/.gitignore
==============================================================================
--- (empty file)
+++ sandbox/numpy/.gitignore 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -0,0 +1,10 @@
+config.log
+.sconf_temp
+.sconsign.dblite
+*.os
+*.succeeded
+libs/numpy/example/dtype
+libs/numpy/example/fromdata
+libs/numpy/example/ndarray
+libs/numpy/example/simple
+libs/numpy/example/ufunc

Added: sandbox/numpy/README
==============================================================================
--- (empty file)
+++ sandbox/numpy/README 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -0,0 +1,80 @@
+Boost.NumPy is an extension for Boost.Python that adds NumPy support.
+
+It is intended as a replacement for the old numeric support in
+Boost.Python proper, which is now out-of-date and does not support
+C/C++ pointer access to the data. Because it builds against the NumPy
+headers and hence has a dependency that Boost.Python does not, it is
+intended to be built as a separate library. This is also not intended
+to be a high-level C++ array library; it would be more accurate to
+consider it a C++ NumPy API, with the intent of making the NumPy C-API
+available in a form that is safer and more convenient for C++ users
+(and particularly those using Boost.Python, of course).
+
+THIS IS NOT AN OFFICIAL BOOST LIBRARY
+
+...we're just calling it Boost.NumPy right now because that clearly
+indicates that it's for Boost.Python and NumPy. We do intend to
+propose it for inclusion in Boost eventually.
+
+
+INSTALLATION
+
+We have provided both a Boost.Build and an SCons build system. At
+the moment, we recommend using the latter. Building should be as
+simple as running "scons" and "scons install", but you may need
+to use the "--with-boost*" options (see "scons --help") to specify
+where to find Boost. The Python that is used by SCons will
+be the one built against.
+
+
+DOCUMENTATION
+
+More documentation on how to use the library can be found in
+libs/numpy/doc, but it may be most useful to start with the
+examples in libs/numpy/examples. The headers files are also
+well documented and are intended to serve as a reference.
+
+
+ISSUES AND NEW FEATURES
+
+Please create an issue on the GitHub site at:
+
+https://github.com/ndarray/Boost.NumPy/issues
+
+
+CONTACT
+
+Please send email questions to:
+
+ndarray-dev_at_[hidden]
+
+...but I would prefer bug reports and feature requests to go to
+the GitHub issues list (see above).
+
+
+MULTI-PLATFORM SUPPORT
+
+The vast majority of development has happened on Linux/g++, and while
+we have taken some steps to support MacOS/clang, there hasn't been
+much testing. There has been no testing on Windows, though we have
+no reason to believe anything we've done won't work on Windows.
+
+In short, we'd really love to have some testing on additional platforms,
+especially from people who know their way around SCons, NumPy, or
+Boost.Python.
+
+
+HISTORY/AUTHORS
+
+Boost.NumPy was originally written by Jim Bosch as part of the
+"ndarray" C++ library, then reorganized into a standalone component,
+cleaned up, and documented as part of a Boost-sponsored
+Google Summer of Code by Ankit Daftery, mentored by Stefan Seefeld.
+
+The project is hosted both on the Boost Sandbox:
+
+https://svn.boost.org/svn/boost/sandbox/numpy
+
+and on GitHub:
+
+https://github.com/ndarray/Boost.NumPy
\ No newline at end of file

Modified: sandbox/numpy/SConscript
==============================================================================
--- sandbox/numpy/SConscript (original)
+++ sandbox/numpy/SConscript 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -4,6 +4,29 @@
 
 import os
 import sys
+import subprocess
+from SCons.SConf import CheckContext
+
+def setupPaths(env, prefix, include, lib):
+ if prefix is not None:
+ if include is None:
+ include = os.path.join(prefix, "include")
+ if lib is None:
+ lib = os.path.join(prefix, "lib")
+ if include:
+ env.PrependUnique(CPPPATH=[include])
+ if lib:
+ env.PrependUnique(LIBPATH=[lib])
+AddMethod(Environment, setupPaths)
+
+def checkLibs(context, try_libs, source_file):
+ init_libs = context.env.get('LIBS', [])
+ context.env.PrependUnique(LIBS=[try_libs])
+ result = context.TryLink(source_file, '.cpp')
+ if not result :
+ context.env.Replace(LIBS=init_libs)
+ return result
+AddMethod(CheckContext, checkLibs)
 
 def CheckPython(context):
     python_source_file = """
@@ -21,7 +44,7 @@
     except ImportError:
         context.Result(0)
         print 'Failed to import distutils.sysconfig.'
- Exit(1)
+ return False
     context.env.AppendUnique(CPPPATH=[distutils.sysconfig.get_python_inc()])
     libDir = distutils.sysconfig.get_config_var("LIBDIR")
     context.env.AppendUnique(LIBPATH=[libDir])
@@ -34,7 +57,7 @@
              if f != "-L"]
     context.env.MergeFlags(" ".join(flags))
     result, output = context.TryRun(python_source_file,'.cpp')
- if not result and sys.platform == 'darwin':
+ if not result and context.env["PLATFORM"] == 'darwin':
         # Sometimes we need some extra stuff on Mac OS
         frameworkDir = libDir # search up the libDir tree for the proper home for frameworks
         while frameworkDir and frameworkDir != "/":
@@ -45,16 +68,18 @@
                     print (
                         "Expected to find Python in framework directory %s, but it isn't there"
                         % frameworkDir)
- Exit(1)
+ return False
                 break
         context.env.AppendUnique(LDFLAGS="-F%s" % frameworkDir)
         result, output = context.TryRun(python_source_file,'.cpp')
     if not result:
         context.Result(0)
         print "Cannot run program built with Python."
- Exit(1)
+ return False
+ if context.env["PLATFORM"] == "darwin":
+ context.env["LDMODULESUFFIX"] = ".so"
     context.Result(1)
- return 1
+ return True
 
 def CheckNumPy(context):
     numpy_source_file = """
@@ -97,28 +122,20 @@
         print ' Alternatively, you can reinstall SCons with your preferred python.'
         print '2) Check that if you open a python session from the command line,'
         print ' import numpy is successful there.'
- Exit(1)
+ return False
     context.env.Append(CPPPATH=numpy.get_include())
- result = CheckLibs(context,[''],numpy_source_file)
+ result = context.checkLibs([''],numpy_source_file)
     if not result:
         context.Result(0)
         print "Cannot build against NumPy."
- Exit(1)
+ return False
     result, output = context.TryRun(numpy_source_file,'.cpp')
     if not result:
         context.Result(0)
         print "Cannot run program built with NumPy."
- Exit(1)
+ return False
     context.Result(1)
- return 1
-
-def CheckLibs(context, try_libs, source_file):
- init_libs = context.env['LIBS']
- context.env.PrependUnique(LIBS=[try_libs])
- result = context.TryLink(source_file, '.cpp')
- if not result :
- context.env.Replace(LIBS=init_libs)
- return result
+ return True
 
 def CheckBoostPython(context):
     bp_source_file = """
@@ -134,86 +151,85 @@
 }
 """
     context.Message('Checking if we can build against Boost.Python... ')
- boost_prefix = GetOption("boost_prefix")
- boost_include = GetOption("boost_include")
- boost_lib = GetOption("boost_lib")
- if boost_prefix is not None:
- if boost_include is None:
- boost_include = os.path.join(boost_prefix, "include")
- if boost_lib is None:
- boost_lib = os.path.join(boost_prefix, "lib")
- if boost_include:
- context.env.AppendUnique(CPPPATH=[boost_include])
- if boost_lib:
- context.env.AppendUnique(LIBPATH=[boost_lib])
+ context.env.setupPaths(
+ prefix = GetOption("boost_prefix"),
+ include = GetOption("boost_include"),
+ lib = GetOption("boost_lib")
+ )
     result = (
- CheckLibs(context, [''], bp_source_file) or
- CheckLibs(context, ['boost_python'], bp_source_file) or
- CheckLibs(context, ['boost_python-mt'], bp_source_file)
+ context.checkLibs([''], bp_source_file) or
+ context.checkLibs(['boost_python'], bp_source_file) or
+ context.checkLibs(['boost_python-mt'], bp_source_file)
         )
     if not result:
         context.Result(0)
         print "Cannot build against Boost.Python."
- Exit(1)
+ return False
     result, output = context.TryRun(bp_source_file, '.cpp')
     if not result:
         context.Result(0)
         print "Cannot build against Boost.Python."
- Exit(1)
+ return False
     context.Result(1)
- return 1
+ return True
 
 # Setup command-line options
-AddOption("--prefix", dest="prefix", type="string", nargs=1, action="store",
- metavar="DIR", default="/usr/local", help="installation prefix")
-AddOption("--with-boost", dest="boost_prefix", type="string", nargs=1, action="store",
- metavar="DIR", default=os.environ.get("BOOST_DIR"),
- help="prefix for Boost libraries; should have 'include' and 'lib' subdirectories")
-AddOption("--with-boost-include", dest="boost_include", type="string", nargs=1, action="store",
- metavar="DIR", help="location of Boost header files")
-AddOption("--with-boost-lib", dest="boost_lib", type="string", nargs=1, action="store",
- metavar="DIR", help="location of Boost libraries")
-
-# Initialize environment
-env = Environment()
-env.AppendUnique(CPPPATH="#.")
-
-# Propogate external environment variables
-if os.environ.has_key("LD_LIBRARY_PATH"):
- env["ENV"]["LD_LIBRARY_PATH"] = os.environ["LD_LIBRARY_PATH"]
-if os.environ.has_key("DYLD_LIBRARY_PATH"):
- env["ENV"]["DYLD_LIBRARY_PATH"] = os.environ["DYLD_LIBRARY_PATH"]
-if os.environ.has_key("PYTHONPATH"):
- env["ENV"]["PYTHONPATH"] = os.environ["PYTHONPATH"]
-
-# Configure dependencies
-if not GetOption("help") and not GetOption("clean"):
- config = env.Configure(
- custom_tests = {
- "CheckPython": CheckPython,
- "CheckNumPy": CheckNumPy,
- "CheckBoostPython": CheckBoostPython,
- }
- )
- config.CheckPython()
- config.CheckNumPy()
- config.CheckBoostPython()
- env = config.Finish()
-
-# Setup build targets
-lib = SConscript(os.path.join("libs", "numpy", "src", "SConscript"), exports='env')
-example = SConscript(os.path.join("libs", "numpy", "example", "SConscript"), exports='env')
-test = SConscript(os.path.join("libs", "numpy", "test", "SConscript"), exports='env')
-
-prefix = Dir(GetOption("prefix")).abspath
-
-env.Alias("install", env.Install(os.path.join(prefix, "lib"), lib))
-for header in ("dtype.hpp", "invoke_matching.hpp", "matrix.hpp",
- "ndarray.hpp", "numpy_object_mgr_traits.hpp",
- "scalars.hpp", "ufunc.hpp",):
- env.Alias("install", env.Install(os.path.join(prefix, "include", "boost", "numpy"),
- os.path.join("boost", "numpy", header)))
-env.Alias("install", env.Install(os.path.join(prefix, "include", "boost"),
- os.path.join("boost", "numpy.hpp")))
+def setupOptions():
+ AddOption("--prefix", dest="prefix", type="string", nargs=1, action="store",
+ metavar="DIR", default="/usr/local", help="installation prefix")
+ AddOption("--install-headers", dest="install_headers", type="string", nargs=1, action="store",
+ metavar="DIR", help="location to install header files (overrides --prefix for headers)")
+ AddOption("--install-lib", dest="install_lib", type="string", nargs=1, action="store",
+ metavar="DIR", help="location to install libraries (overrides --prefix for libraries)")
+ AddOption("--with-boost", dest="boost_prefix", type="string", nargs=1, action="store",
+ metavar="DIR", default=os.environ.get("BOOST_DIR"),
+ help="prefix for Boost libraries; should have 'include' and 'lib' subdirectories")
+ AddOption("--with-boost-include", dest="boost_include", type="string", nargs=1, action="store",
+ metavar="DIR", help="location of Boost header files")
+ AddOption("--with-boost-lib", dest="boost_lib", type="string", nargs=1, action="store",
+ metavar="DIR", help="location of Boost libraries")
+ AddOption("--rpath", dest="custom_rpath", type="string", action="append",
+ help="runtime link paths to add to libraries and executables; may be passed more than once")
+ variables = Variables()
+ variables.Add("CCFLAGS", default=os.environ.get("CCFLAGS", "-O2 -g"), help="compiler flags")
+ return variables
+
+def makeEnvironment(variables):
+ shellEnv = {}
+ for key in ("PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH", "PYTHONPATH"):
+ if key in os.environ:
+ shellEnv[key] = os.environ[key]
+ env = Environment(variables=variables, ENV=shellEnv)
+ if os.environ.has_key("CCFLAGS"):
+ env.AppendUnique(CCFLAGS = os.environ["CCFLAGS"])
+ custom_rpath = GetOption("custom_rpath")
+ if custom_rpath is not None:
+ env.AppendUnique(RPATH=custom_rpath)
+ boost_lib = GetOption ('boost_lib')
+ if boost_lib is not None:
+ env.PrependUnique(LIBPATH=boost_lib)
+ return env
+
+def setupTargets(env, root="."):
+ lib = SConscript(os.path.join(root, "libs", "numpy", "src", "SConscript"), exports='env')
+ example = SConscript(os.path.join(root, "libs", "numpy", "example", "SConscript"), exports='env')
+ test = SConscript(os.path.join(root, "libs", "numpy", "test", "SConscript"), exports='env')
+ prefix = Dir(GetOption("prefix")).abspath
+ install_headers = GetOption('install_headers')
+ install_lib = GetOption('install_lib')
+ if not install_headers:
+ install_headers = os.path.join(prefix, "include")
+ if not install_lib:
+ install_lib = os.path.join(prefix, "lib")
+ env.Alias("install", env.Install(install_lib, lib))
+ for header in ("dtype.hpp", "invoke_matching.hpp", "matrix.hpp",
+ "ndarray.hpp", "numpy_object_mgr_traits.hpp",
+ "scalars.hpp", "ufunc.hpp",):
+ env.Alias("install", env.Install(os.path.join(install_headers, "boost", "numpy"),
+ os.path.join(root, "boost", "numpy", header)))
+ env.Alias("install", env.Install(os.path.join(install_headers, "boost"),
+ os.path.join(root, "boost", "numpy.hpp")))
+
+checks = {"CheckPython": CheckPython, "CheckNumPy": CheckNumPy, "CheckBoostPython": CheckBoostPython}
 
-Return("env")
+Return("setupOptions", "makeEnvironment", "setupTargets", "checks")

Modified: sandbox/numpy/SConstruct
==============================================================================
--- sandbox/numpy/SConstruct (original)
+++ sandbox/numpy/SConstruct 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1 +1,15 @@
-SConscript("SConscript")
+# -*- python -*-
+setupOptions, makeEnvironment, setupTargets, checks = SConscript("SConscript")
+
+variables = setupOptions()
+
+env = makeEnvironment(variables)
+env.AppendUnique(CPPPATH="#.")
+
+if not GetOption("help") and not GetOption("clean"):
+ config = env.Configure(custom_tests=checks)
+ if not (config.CheckPython() and config.CheckNumPy() and config.CheckBoostPython()):
+ Exit(1)
+ env = config.Finish()
+
+setupTargets(env)

Modified: sandbox/numpy/boost/numpy.hpp
==============================================================================
--- sandbox/numpy/boost/numpy.hpp (original)
+++ sandbox/numpy/boost/numpy.hpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -23,9 +23,10 @@
  * It should probably be the first line inside BOOST_PYTHON_MODULE.
  *
  * @internal This just calls the Numpy C-API functions "import_array()"
- * and "import_ufunc()".
+ * and "import_ufunc()", and then calls
+ * dtype::register_scalar_converters().
  */
-void initialize();
+void initialize(bool register_scalar_converters=true);
 
 } // namespace boost::numpy
 } // namespace boost

Modified: sandbox/numpy/boost/numpy/dtype.hpp
==============================================================================
--- sandbox/numpy/boost/numpy/dtype.hpp (original)
+++ sandbox/numpy/boost/numpy/dtype.hpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -12,18 +12,14 @@
 #include <boost/mpl/for_each.hpp>
 #include <boost/type_traits/add_pointer.hpp>
 
-namespace boost
-{
-namespace numpy
-{
+namespace boost { 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
-{
+class dtype : public python::object {
   static python::detail::new_reference convert(python::object::object_cref arg, bool align);
 public:
 
@@ -47,19 +43,59 @@
   /// @brief Return the size of the data type in bytes.
   int get_itemsize() const;
 
+ /**
+ * @brief Register from-Python converters for NumPy's built-in array scalar types.
+ *
+ * This is usually called automatically by initialize(), and shouldn't be called twice
+ * (doing so just adds unused converters to the Boost.Python registry).
+ */
+ static void register_scalar_converters();
+
   BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dtype, python::object);
 
 };
 
-} // namespace boost::numpy
-
-namespace python
-{
-namespace converter
+namespace detail
 {
+
+template <int bits, bool isUnsigned> dtype get_int_dtype();
+
+template <int bits> dtype get_float_dtype();
+
+template <int bits> dtype get_complex_dtype();
+
+template <typename T, bool isInt=boost::is_integral<T>::value>
+struct builtin_dtype;
+
+template <typename T>
+struct builtin_dtype<T,true> {
+ static dtype get() { return get_int_dtype< 8*sizeof(T), boost::is_unsigned<T>::value >(); }
+};
+
+template <>
+struct builtin_dtype<bool,true> {
+ static dtype get();
+};
+
+template <typename T>
+struct builtin_dtype<T,false> {
+ static dtype get() { return get_float_dtype< 8*sizeof(T) >(); }
+};
+
+template <typename T>
+struct builtin_dtype< std::complex<T>, false > {
+ static dtype get() { return get_complex_dtype< 16*sizeof(T) >(); }
+};
+
+} // namespace detail
+
+template <typename T>
+inline dtype dtype::get_builtin() { return detail::builtin_dtype<T>::get(); }
+
+}} // namespace boost::numpy
+
+namespace boost { namespace python { namespace converter {
 NUMPY_OBJECT_MANAGER_TRAITS(numpy::dtype);
-} // namespace boost::python::converter
-} // namespace boost::python
-} // namespace boost
+}}} // namespace boost::python::converter
 
 #endif // !BOOST_NUMPY_DTYPE_HPP_INCLUDED

Modified: sandbox/numpy/boost/numpy/matrix.hpp
==============================================================================
--- sandbox/numpy/boost/numpy/matrix.hpp (original)
+++ sandbox/numpy/boost/numpy/matrix.hpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -52,6 +52,20 @@
 
 };
 
+/**
+ * @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();
+ }
+};
+
 } // namespace boost::numpy
 namespace python
 {

Modified: sandbox/numpy/libs/numpy/src/dtype.cpp
==============================================================================
--- sandbox/numpy/libs/numpy/src/dtype.cpp (original)
+++ sandbox/numpy/libs/numpy/src/dtype.cpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1,58 +1,78 @@
 #define BOOST_NUMPY_INTERNAL
 #include <boost/numpy/internal.hpp>
 
-#define NUMPY_DTYPE_TRAITS_BUILTIN(ctype,code) \
-template <> struct dtype_traits<ctype> \
-{ \
- static dtype get() \
- { \
- return dtype(python::detail::new_reference \
- (reinterpret_cast<PyObject*>(PyArray_DescrFromType(code)))); \
- } \
-}; \
-template dtype dtype::get_builtin<ctype>()
-
-#define NUMPY_DTYPE_TRAITS_COMPLEX(creal, ctype, code) \
-template <> struct dtype_traits< std::complex<creal> > \
-{ \
- static dtype get() \
- { \
- if (sizeof(ctype) != sizeof(std::complex<creal>)) \
- { \
- PyErr_SetString(PyExc_TypeError, "Cannot reinterpret std::complex<T> as T[2]"); \
- python::throw_error_already_set(); \
- } \
- return dtype(python::detail::new_reference \
- (reinterpret_cast<PyObject*>(PyArray_DescrFromType(code)))); \
- } \
-}; \
-template dtype dtype::get_builtin< std::complex<creal> >()
-
-namespace boost
-{
-namespace python
-{
-namespace converter
-{
+#define DTYPE_FROM_CODE(code) \
+ dtype(python::detail::new_reference(reinterpret_cast<PyObject*>(PyArray_DescrFromType(code))))
+
+#define BUILTIN_INT_DTYPE(bits) \
+ template <> struct builtin_int_dtype< bits, false > { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_INT ## bits); } \
+ }; \
+ template <> struct builtin_int_dtype< bits, true > { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_UINT ## bits); } \
+ }; \
+ template dtype get_int_dtype< bits, false >(); \
+ template dtype get_int_dtype< bits, true >()
+
+#define BUILTIN_FLOAT_DTYPE(bits) \
+ template <> struct builtin_float_dtype< bits > { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_FLOAT ## bits); } \
+ }; \
+ template dtype get_float_dtype< bits >()
+
+#define BUILTIN_COMPLEX_DTYPE(bits) \
+ template <> struct builtin_complex_dtype< bits > { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_COMPLEX ## bits); } \
+ }; \
+ template dtype get_complex_dtype< bits >()
+
+namespace boost { namespace python { namespace converter {
 NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArrayDescr_Type, numpy::dtype)
-} // namespace boost::python::converter
-} // namespace boost::python
+}}} // namespace boost::python::converter
+
+namespace boost { namespace numpy {
+
+namespace detail {
+
+dtype builtin_dtype<bool,true>::get() { return DTYPE_FROM_CODE(NPY_BOOL); }
+
+template <int bits, bool isUnsigned> struct builtin_int_dtype;
+template <int bits> struct builtin_float_dtype;
+template <int bits> struct builtin_complex_dtype;
 
-namespace numpy
-{
+template <int bits, bool isUnsigned> dtype get_int_dtype() {
+ return builtin_int_dtype<bits,isUnsigned>::get();
+}
+template <int bits> dtype get_float_dtype() { return builtin_float_dtype<bits>::get(); }
+template <int bits> dtype get_complex_dtype() { return builtin_complex_dtype<bits>::get(); }
+
+BUILTIN_INT_DTYPE(8);
+BUILTIN_INT_DTYPE(16);
+BUILTIN_INT_DTYPE(32);
+BUILTIN_INT_DTYPE(64);
+BUILTIN_FLOAT_DTYPE(32);
+BUILTIN_FLOAT_DTYPE(64);
+BUILTIN_COMPLEX_DTYPE(64);
+BUILTIN_COMPLEX_DTYPE(128);
+#if NPY_BITSOF_LONGDOUBLE > NPY_BITSOF_DOUBLE
+template <> struct builtin_float_dtype< NPY_BITSOF_LONGDOUBLE > {
+ static dtype get() { return DTYPE_FROM_CODE(NPY_LONGDOUBLE); }
+};
+template dtype get_float_dtype< NPY_BITSOF_LONGDOUBLE >();
+template <> struct builtin_complex_dtype< 2 * NPY_BITSOF_LONGDOUBLE > {
+ static dtype get() { return DTYPE_FROM_CODE(NPY_CLONGDOUBLE); }
+};
+template dtype get_complex_dtype< 2 * NPY_BITSOF_LONGDOUBLE >();
+#endif
 
-template <typename T> struct dtype_traits;
+} // namespace detail
 
-python::detail::new_reference dtype::convert(python::object const & arg, bool align)
-{
+python::detail::new_reference dtype::convert(python::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
- {
+ } else {
     if (PyArray_DescrConverter(arg.ptr(), &obj) < 0)
       python::throw_error_already_set();
   }
@@ -61,42 +81,72 @@
 
 int dtype::get_itemsize() const { return reinterpret_cast<PyArray_Descr*>(ptr())->elsize;}
 
+namespace {
+
+namespace pyconv = boost::python::converter;
+
 template <typename T>
-dtype dtype::get_builtin() { return dtype_traits<T>::get(); }
+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 void * convertible(PyObject * obj) {
+ if (obj->ob_type == get_pytype()) {
+ return obj;
+ } else {
+ 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;
+ }
 
-NUMPY_DTYPE_TRAITS_BUILTIN(bool, NPY_BOOL);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_ubyte, NPY_UBYTE);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_byte, NPY_BYTE);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_ushort, NPY_USHORT);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_short, NPY_SHORT);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_uint, NPY_UINT);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_int, NPY_INT);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_ulong, NPY_ULONG);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_long, NPY_LONG);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_longlong, NPY_LONGLONG);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_float, NPY_FLOAT);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_double, NPY_DOUBLE);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_longdouble, NPY_LONGDOUBLE);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_cfloat, NPY_CFLOAT);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_cdouble, NPY_CDOUBLE);
-NUMPY_DTYPE_TRAITS_BUILTIN(npy_clongdouble, NPY_CLONGDOUBLE);
-NUMPY_DTYPE_TRAITS_COMPLEX(float, npy_cfloat, NPY_CFLOAT);
-NUMPY_DTYPE_TRAITS_COMPLEX(double, npy_cdouble, NPY_CDOUBLE);
-NUMPY_DTYPE_TRAITS_COMPLEX(long double, npy_clongdouble, NPY_CLONGDOUBLE);
-
-#if 0
-template <> struct dtype_traits<bool>
-{
- static dtype get()
- {
- if (sizeof(bool) == sizeof(npy_ubyte)) return dtype_traits<npy_ubyte>::get();
- if (sizeof(bool) == sizeof(npy_bool)) return dtype_traits<npy_bool>::get();
- PyErr_SetString(PyExc_TypeError, "Cannot determine numpy dtype corresponding to C++ bool.");
- python::throw_error_already_set();
+ static void declare() {
+ pyconv::registry::push_back(
+ &convertible, &convert, python::type_id<T>()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &get_pytype
+#endif
+ );
   }
+
 };
-template dtype dtype::get_builtin<bool>();
+
+} // anonymous
+
+void dtype::register_scalar_converters() {
+ array_scalar_converter<bool>::declare();
+ array_scalar_converter<npy_uint8>::declare();
+ array_scalar_converter<npy_int8>::declare();
+ array_scalar_converter<npy_uint16>::declare();
+ array_scalar_converter<npy_int16>::declare();
+ array_scalar_converter<npy_uint32>::declare();
+ array_scalar_converter<npy_int32>::declare();
+ array_scalar_converter<npy_uint64>::declare();
+ array_scalar_converter<npy_int64>::declare();
+ array_scalar_converter<float>::declare();
+ array_scalar_converter<double>::declare();
+ array_scalar_converter< std::complex<float> >::declare();
+ array_scalar_converter< std::complex<double> >::declare();
+#if NPY_BITSOF_LONGDOUBLE > NPY_BITSOF_DOUBLE
+ array_scalar_converter<long double>::declare();
+ array_scalar_converter< std::complex<long double> >::declare();
 #endif
+}
 
 } // namespace boost::numpy
 } // namespace boost

Modified: sandbox/numpy/libs/numpy/src/numpy.cpp
==============================================================================
--- sandbox/numpy/libs/numpy/src/numpy.cpp (original)
+++ sandbox/numpy/libs/numpy/src/numpy.cpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1,15 +1,18 @@
 #define BOOST_NUMPY_INTERNAL_MAIN
 #include <boost/numpy/internal.hpp>
+#include <boost/numpy/dtype.hpp>
 
 namespace boost
 {
 namespace numpy
 {
 
-void initialize()
+void initialize(bool register_scalar_converters)
 {
   import_array();
   import_ufunc();
+ if (register_scalar_converters)
+ dtype::register_scalar_converters();
 }
 
 }

Modified: sandbox/numpy/libs/numpy/test/SConscript
==============================================================================
--- sandbox/numpy/libs/numpy/test/SConscript (original)
+++ sandbox/numpy/libs/numpy/test/SConscript 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -22,8 +22,8 @@
     env.Depends(run, dependencies)
     return run
 
-for name in ("ufunc", "templates", "ndarray", "indexing", "shapes"):
- mod = test_env.SharedLibrary("%s_mod" % name, "%s_mod.cpp" % name, SHLIBPREFIX="")
+for name in ("dtype", "ufunc", "templates", "ndarray", "indexing", "shapes"):
+ mod = test_env.LoadableModule("%s_mod" % name, "%s_mod.cpp" % name, LDMODULEPREFIX="")
     test.extend(PythonUnitTest(test_env, "%s.py" % name, mod))
 
 Return("test")

Added: sandbox/numpy/libs/numpy/test/dtype.py
==============================================================================
--- (empty file)
+++ sandbox/numpy/libs/numpy/test/dtype.py 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+import dtype_mod
+import unittest
+import numpy
+
+class DtypeTestCase(unittest.TestCase):
+
+ 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)
+ self.assertEqual(fs(s(1)), numpy.dtype(s))
+ self.assertEqual(fu(u(1)), numpy.dtype(u))
+ # these should just use the regular Boost.Python converters
+ self.assertEqual(fs(True), numpy.dtype(s))
+ self.assertEqual(fu(True), numpy.dtype(u))
+ self.assertEqual(fs(int(1)), numpy.dtype(s))
+ self.assertEqual(fu(int(1)), numpy.dtype(u))
+ self.assertEqual(fs(long(1)), numpy.dtype(s))
+ self.assertEqual(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)
+ self.assertEqual(ft(t(1)), numpy.dtype(t))
+ # these should just use the regular Boost.Python converters
+ self.assertEqual(ft(True), numpy.dtype(t))
+ if name != "bool_":
+ self.assertEqual(ft(int(1)), numpy.dtype(t))
+ self.assertEqual(ft(long(1)), numpy.dtype(t))
+
+
+ def testFloats(self):
+ f = numpy.float32
+ c = numpy.complex64
+ self.assertEqual(dtype_mod.accept_float32(f(numpy.pi)), numpy.dtype(f))
+ self.assertEqual(dtype_mod.accept_complex64(c(1+2j)), numpy.dtype(c))
+ f = numpy.float64
+ c = numpy.complex128
+ self.assertEqual(dtype_mod.accept_float64(f(numpy.pi)), numpy.dtype(f))
+ self.assertEqual(dtype_mod.accept_complex128(c(1+2j)), numpy.dtype(c))
+ if hasattr(numpy, "longdouble"):
+ f = numpy.longdouble
+ c = numpy.clongdouble
+ self.assertEqual(dtype_mod.accept_longdouble(f(numpy.pi)), numpy.dtype(f))
+ self.assertEqual(dtype_mod.accept_clongdouble(c(1+2j)), numpy.dtype(c))
+
+
+if __name__=="__main__":
+ unittest.main()

Added: sandbox/numpy/libs/numpy/test/dtype_mod.cpp
==============================================================================
--- (empty file)
+++ sandbox/numpy/libs/numpy/test/dtype_mod.cpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -0,0 +1,42 @@
+#include <boost/numpy.hpp>
+#include <boost/cstdint.hpp>
+
+namespace p = boost::python;
+namespace np = boost::numpy;
+
+template <typename T>
+np::dtype accept(T) {
+ return np::dtype::get_builtin<T>();
+}
+
+
+BOOST_PYTHON_MODULE(dtype_mod)
+{
+ np::initialize();
+ // integers, by number of bits
+ p::def("accept_int8", accept<boost::int8_t>);
+ p::def("accept_uint8", accept<boost::uint8_t>);
+ p::def("accept_int16", accept<boost::int16_t>);
+ p::def("accept_uint16", accept<boost::uint16_t>);
+ p::def("accept_int32", accept<boost::int32_t>);
+ p::def("accept_uint32", accept<boost::uint32_t>);
+ p::def("accept_int64", accept<boost::int64_t>);
+ p::def("accept_uint64", accept<boost::uint64_t>);
+ // integers, by C name according to NumPy
+ p::def("accept_bool_", accept<bool>);
+ p::def("accept_byte", accept<signed char>);
+ p::def("accept_ubyte", accept<unsigned char>);
+ p::def("accept_short", accept<short>);
+ p::def("accept_ushort", accept<unsigned short>);
+ p::def("accept_intc", accept<int>);
+ p::def("accept_uintc", accept<unsigned int>);
+ // floats and complex
+ p::def("accept_float32", accept<float>);
+ p::def("accept_complex64", accept< std::complex<float> >);
+ p::def("accept_float64", accept<double>);
+ p::def("accept_complex128", accept< std::complex<double> >);
+ if (sizeof(long double) > sizeof(double)) {
+ p::def("accept_longdouble", accept<long double>);
+ p::def("accept_clongdouble", accept< std::complex<long double> >);
+ }
+}

Modified: sandbox/numpy/libs/numpy/test/indexing.py
==============================================================================
--- sandbox/numpy/libs/numpy/test/indexing.py (original)
+++ sandbox/numpy/libs/numpy/test/indexing.py 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1,48 +1,50 @@
+#!/usr/bin/env python
+
 import unittest
 import numpy
 import indexing_mod
 
 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)
- for i in range(-10,0):
- numpy.testing.assert_equal(indexing_mod.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)
-
- 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)
-
- 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)
- chk = numpy.array([[0,1],[2,3]])
- numpy.testing.assert_equal(indexing_mod.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)
- 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)
- 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)
+ def testSingle(self):
+ x = numpy.arange(0,10)
+ for i in range(0,10):
+ numpy.testing.assert_equal(indexing_mod.single(x,i), i)
+ for i in range(-10,0):
+ numpy.testing.assert_equal(indexing_mod.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)
+
+ 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)
+
+ 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)
+ chk = numpy.array([[0,1],[2,3]])
+ numpy.testing.assert_equal(indexing_mod.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)
+ 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)
+ 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)
 
 if __name__=="__main__":
- unittest.main()
+ unittest.main()

Modified: sandbox/numpy/libs/numpy/test/ndarray.py
==============================================================================
--- sandbox/numpy/libs/numpy/test/ndarray.py (original)
+++ sandbox/numpy/libs/numpy/test/ndarray.py 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1,62 +1,74 @@
+#!/usr/bin/env python
+
 import ndarray_mod
 import unittest
 import numpy
 
 class TestNdarray(unittest.TestCase):
-
- def testNdzeros(self):
- for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
- 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)
- a2 = v.reshape(a1.shape)
- self.assertEqual(shape,a1.shape)
- self.assert_((a1 == a2).all())
-
- def testNdarray(self):
- a = range(0,60)
- 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)
- self.assert_((a1 == v).all())
- self.assert_((a2 == v).all())
- for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)):
- a1 = a1.reshape(shape)
- self.assertEqual(shape,a1.shape)
- a2 = a2.reshape(shape)
- self.assertEqual(shape,a2.shape)
-
- def testNdempty(self):
- 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)
- self.assertEqual(shape,a1.shape)
- self.assertEqual(shape,a2.shape)
-
- def testTranspose(self):
- for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
- dt = numpy.dtype(dtp)
- 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)
- self.assertEqual(a1.shape,a2.shape)
-
- def testSqueeze(self):
- a1 = numpy.array([[[3,4,5]]])
- a2 = a1.squeeze()
- a1 = ndarray_mod.squeeze(a1)
- self.assertEqual(a1.shape,a2.shape)
-
- def testReshape(self):
- a1 = numpy.empty((2,2))
- a2 = ndarray_mod.reshape(a1,(1,4))
- self.assertEqual(a2.shape,(1,4))
+
+ def testNdzeros(self):
+ for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ 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)
+ a2 = v.reshape(a1.shape)
+ self.assertEqual(shape,a1.shape)
+ self.assert_((a1 == a2).all())
+
+ def testNdzeros_matrix(self):
+ 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)
+ a2 = numpy.matrix(numpy.zeros(shape, dtype=dtp))
+ self.assertEqual(shape,a1.shape)
+ self.assert_((a1 == a2).all())
+ self.assertEqual(type(a1), type(a2))
+
+ def testNdarray(self):
+ a = range(0,60)
+ 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)
+ self.assert_((a1 == v).all())
+ self.assert_((a2 == v).all())
+ for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)):
+ a1 = a1.reshape(shape)
+ self.assertEqual(shape,a1.shape)
+ a2 = a2.reshape(shape)
+ self.assertEqual(shape,a2.shape)
+
+ def testNdempty(self):
+ 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)
+ self.assertEqual(shape,a1.shape)
+ self.assertEqual(shape,a2.shape)
+
+ def testTranspose(self):
+ for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ dt = numpy.dtype(dtp)
+ 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)
+ self.assertEqual(a1.shape,a2.shape)
+
+ def testSqueeze(self):
+ a1 = numpy.array([[[3,4,5]]])
+ a2 = a1.squeeze()
+ a1 = ndarray_mod.squeeze(a1)
+ self.assertEqual(a1.shape,a2.shape)
+
+ def testReshape(self):
+ a1 = numpy.empty((2,2))
+ a2 = ndarray_mod.reshape(a1,(1,4))
+ self.assertEqual(a2.shape,(1,4))
 
 if __name__=="__main__":
- unittest.main()
+ unittest.main()

Modified: sandbox/numpy/libs/numpy/test/ndarray_mod.cpp
==============================================================================
--- sandbox/numpy/libs/numpy/test/ndarray_mod.cpp (original)
+++ sandbox/numpy/libs/numpy/test/ndarray_mod.cpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -24,10 +24,12 @@
 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)
 {
   np::initialize();
   p::def("zeros", zeros);
+ p::def("zeros_matrix", zeros, np::as_matrix<>());
   p::def("array", array2);
   p::def("array", array1);
   p::def("empty", empty1);

Modified: sandbox/numpy/libs/numpy/test/shapes.py
==============================================================================
--- sandbox/numpy/libs/numpy/test/shapes.py (original)
+++ sandbox/numpy/libs/numpy/test/shapes.py 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1,14 +1,16 @@
+#!/usr/bin/env python
+
 import shapes_mod
 import unittest
 import numpy
 
 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)
- self.assertEqual(a1_shape,a1.shape)
+
+ def testShapes(self):
+ a1 = numpy.array([(0,1),(2,3)])
+ a1_shape = (1,4)
+ a1 = shapes_mod.reshape(a1,a1_shape)
+ self.assertEqual(a1_shape,a1.shape)
 
 if __name__=="__main__":
- unittest.main()
+ unittest.main()

Modified: sandbox/numpy/libs/numpy/test/templates.py
==============================================================================
--- sandbox/numpy/libs/numpy/test/templates.py (original)
+++ sandbox/numpy/libs/numpy/test/templates.py 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
 import templates_mod
 import unittest
 import numpy

Modified: sandbox/numpy/libs/numpy/test/ufunc.py
==============================================================================
--- sandbox/numpy/libs/numpy/test/ufunc.py (original)
+++ sandbox/numpy/libs/numpy/test/ufunc.py 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
 import ufunc_mod
 import unittest
 import numpy

Modified: sandbox/numpy/libs/numpy/test/ufunc_mod.cpp
==============================================================================
--- sandbox/numpy/libs/numpy/test/ufunc_mod.cpp (original)
+++ sandbox/numpy/libs/numpy/test/ufunc_mod.cpp 2012-05-13 13:46:46 EDT (Sun, 13 May 2012)
@@ -23,8 +23,8 @@
 BOOST_PYTHON_MODULE(ufunc_mod)
 {
   np::initialize();
- p::class_<UnaryCallable, boost::shared_ptr<UnaryCallable> >("UnaryCallable")
+ p::class_<UnaryCallable>("UnaryCallable")
     .def("__call__", np::unary_ufunc<UnaryCallable>::make());
- p::class_< BinaryCallable, boost::shared_ptr<BinaryCallable> >("BinaryCallable")
+ p::class_< BinaryCallable>("BinaryCallable")
     .def("__call__", np::binary_ufunc<BinaryCallable>::make());
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk