diff --git a/.gitmodules b/.gitmodules index 612e2c90..62c49d0a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "Boost.NumPy"] path = Boost.NumPy - url = git://github.com/ndarray/Boost.NumPy.git + url = https://github.com/ChrislS/Boost.NumPy.git + branch = master diff --git a/Boost.NumPy b/Boost.NumPy index bf73da1b..915781fc 160000 --- a/Boost.NumPy +++ b/Boost.NumPy @@ -1 +1 @@ -Subproject commit bf73da1bce9178d1b0c5e5120926b8b1ca8d1eae +Subproject commit 915781fc8e44eb3d109b8e2adc2ff5933eb0d1ad diff --git a/README b/README index d7926fb3..7a52bb61 100644 --- a/README +++ b/README @@ -15,10 +15,9 @@ an empty Boost.NumPy directory. Even if you don't plan to use Boost.NumPy (which is required only if you want to build the Boost.Python bindings for ndarray), it *is* necessary to checkout the Boost.NumPy source (as parts of the build system is shared). So, -immediately after cloning ndarray, you'll need to run two commands: +immediately after cloning ndarray, you'll need to run: -git submodule init -git submodule update +git submodule update --init --recursive From there, you'll be able to build ndarray and (optionally) Boost.NumPy together just by running "scons" from the root of the diff --git a/SConstruct b/SConstruct index ba5479a4..f1b9c323 100644 --- a/SConstruct +++ b/SConstruct @@ -8,59 +8,14 @@ # of the source distribution, or alternately available at: # https://github.com/ndarray/ndarray # - import os +import sys +sys.path.insert(0, os.path.abspath('Boost.NumPy')) +from SConsChecks import AddLibOptions, GetLibChecks -def CheckBoostTest(context): - source_file = """ -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE config -#include "boost/test/unit_test.hpp" -#include "boost/test/results_reporter.hpp" -#include - -BOOST_AUTO_TEST_CASE(ConfigTestCase) { - boost::unit_test::results_reporter::set_stream(std::cout); - BOOST_CHECK(true); -} -""" - context.Message("Checking for Boost.Test Library...") - context.env.setupPaths( - prefix = GetOption("boost_prefix"), - include = GetOption("boost_include"), - lib = GetOption("boost_lib") - ) - result = ( - context.checkLibs([''], source_file) or - context.checkLibs(['boost_unit_test_framework'], source_file) or - context.checkLibs(['boost_unit_test_framework-mt'], source_file) - ) - if not result: - context.Result(0) - print("Cannot build against Boost.Test.") - return False - result, output = context.TryRun(source_file, '.cpp') - if not result: - context.Result(0) - print("Cannot build against Boost.Test.") - return False - context.Result(1) - return True - -def CheckSwig(context): - context.Message("Checking for SWIG...") - context.env.PrependUnique(SWIGFLAGS = ["-python", "-c++"]) - result, swig_cmd = config.TryAction("which swig > $TARGET") - context.Result(result) - if result: - context.env.AppendUnique(SWIGPATH = ["#include"]) - print("Using SWIG at", swig_cmd.strip()) - return result - -setupOptions, makeEnvironment, setupTargets, checks = SConscript("Boost.NumPy/SConscript") - -checks["CheckBoostTest"] = CheckBoostTest -checks["CheckSwig"] = CheckSwig +setupOptions, makeEnvironment, setupTargets, checks, libs = SConscript("Boost.NumPy/SConscript") +libs.extend(['swig', 'eigen', 'boost.test', 'fftw', 'boost.preprocessor']) +checks = GetLibChecks(libs) variables = setupOptions() @@ -69,7 +24,6 @@ AddOption("--with-eigen", dest="eigen_prefix", type="string", nargs=1, action="s help="prefix for Eigen libraries; should have an 'include' subdirectory") AddOption("--with-eigen-include", dest="eigen_include", type="string", nargs=1, action="store", metavar="DIR", help="location of Eigen header files") - AddOption("--with-fftw", dest="fftw_prefix", type="string", nargs=1, action="store", metavar="DIR", default=os.environ.get("FFTW_DIR"), help="prefix for FFTW libraries; should have 'include' and 'lib' subdirectories") @@ -77,7 +31,6 @@ AddOption("--with-fftw-include", dest="fftw_include", type="string", nargs=1, ac metavar="DIR", help="location of FFTW header files") AddOption("--with-fftw-lib", dest="fftw_lib", type="string", nargs=1, action="store", metavar="DIR", help="location of FFTW library") - building = not GetOption("help") and not GetOption("clean") env = makeEnvironment(variables) @@ -85,18 +38,8 @@ env.AppendUnique(CPPPATH=["#include"]) if building: config = env.Configure(custom_tests=checks) - config.env.setupPaths( - prefix = GetOption("eigen_prefix"), - include = GetOption("eigen_include"), - lib = None - ) - config.env.setupPaths( - prefix = GetOption("fftw_prefix"), - include = GetOption("fftw_include"), - lib = GetOption("fftw_lib") - ) - haveEigen = config.CheckCXXHeader("Eigen/Core") - haveFFTW = config.CheckLibWithHeader("fftw3", "fftw3.h", "C", autoadd=False) + haveEigen = config.CheckEigen() + haveFFTW = config.CheckFFTW() env = config.Finish() else: haveEigen = False @@ -118,6 +61,9 @@ if building: config = pyEnv.Configure(custom_tests=checks) havePython = config.CheckPython() and config.CheckNumPy() haveSwig = havePython and config.CheckSwig() + if haveSwig: + pyEnv.AppendUnique(SWIGPATH = ["#include"]) + config.CheckBoostPP() pyEnv = config.Finish() else: havePython = False @@ -141,6 +87,7 @@ elif building: print("Not building Boost.NumPy component.") headers = SConscript(os.path.join("include", "SConscript"), exports="env") + prefix = Dir(GetOption("prefix")).abspath install_headers = GetOption("install_headers") if not install_headers: @@ -149,5 +96,4 @@ for header in Flatten(headers): relative = os.path.relpath(header.abspath, Dir("#include").abspath) env.Alias("install", env.InstallAs(os.path.join(install_headers, relative), header)) -if False: - tests = SConscript(os.path.join("tests", "SConscript"), exports=["env", "testEnv", "pyEnv", "bpEnv"]) +tests = SConscript(os.path.join("tests", "SConscript"), exports=["env", "testEnv", "pyEnv", "bpEnv"]) diff --git a/include/ndarray/Array.h b/include/ndarray/Array.h index 363c9f34..1d195983 100644 --- a/include/ndarray/Array.h +++ b/include/ndarray/Array.h @@ -86,7 +86,7 @@ class Array : public ArrayBaseN< Array > { * * This is implemented in initialization.h. */ - explicit Array(int n1, int n2=1, int n3=1, int n4=1, int n5=1, int n6=1, int n7=1, int n8=1); + explicit Array(std::size_t n1, std::size_t n2=1, std::size_t n3=1, std::size_t n4=1, std::size_t n5=1, std::size_t n6=1, std::size_t n7=1, std::size_t n8=1); /** * @brief Non-converting shallow assignment. diff --git a/include/ndarray/ArrayBase.h b/include/ndarray/ArrayBase.h index 4b6c048c..06d050de 100644 --- a/include/ndarray/ArrayBase.h +++ b/include/ndarray/ArrayBase.h @@ -17,7 +17,8 @@ * @brief Definitions for ArrayBase. */ - +#include + #include #include "ndarray/ExpressionBase.h" @@ -60,7 +61,7 @@ class ArrayBase : public ExpressionBase { /// @brief Number of guaranteed row-major contiguous dimensions, counted from the end (boost::mpl::int_). typedef typename Traits::RMC RMC; /// @brief Vector type for N-dimensional indices. - typedef Vector Index; + typedef Vector Index; /// @brief ArrayRef to a reverse-ordered contiguous array; the result of a call to transpose(). typedef ArrayRef FullTranspose; /// @brief ArrayRef to a noncontiguous array; the result of a call to transpose(...). @@ -71,16 +72,24 @@ class ArrayBase : public ExpressionBase { typedef ArrayRef Deep; /// @brief Return a single subarray. - Reference operator[](int n) const { + Reference operator[](std::size_t n) const { return Traits::makeReference( - this->_data + n * this->template getStride<0>(), + this->_data + n * this-> + #ifndef _MSC_VER + template + #endif + getStride<0>(), this->_core ); } /// @brief Return a single element from the array. Element & operator[](Index const & i) const { - return *(this->_data + this->_core->template computeOffset(i)); + return *(this->_data + this->_core-> + #ifndef _MSC_VER + template + #endif + computeOffset(i)); } /// @brief Return an Iterator to the beginning of the array. @@ -88,16 +97,32 @@ class ArrayBase : public ExpressionBase { return Traits::makeIterator( this->_data, this->_core, - this->template getStride<0>() + this-> + #ifndef _MSC_VER + template + #endif + getStride<0>() ); } /// @brief Return an Iterator to one past the end of the array. Iterator end() const { return Traits::makeIterator( - this->_data + this->template getSize<0>() * this->template getStride<0>(), + this->_data + this-> + #ifndef _MSC_VER + template + #endif + getSize<0>() * this-> + #ifndef _MSC_VER + template + #endif + getStride<0>(), this->_core, - this->template getStride<0>() + this-> + #ifndef _MSC_VER + template + #endif + getStride<0>() ); } @@ -111,12 +136,12 @@ class ArrayBase : public ExpressionBase { Manager::Ptr getManager() const { return this->_core->getManager(); } /// @brief Return the size of a specific dimension. - template int getSize() const { + template size_t getSize() const { return detail::getDimension

(*this->_core).getSize(); } /// @brief Return the stride in a specific dimension. - template int getStride() const { + template std::size_t getStride() const { return detail::getDimension

(*this->_core).getStride(); } @@ -127,15 +152,15 @@ class ArrayBase : public ExpressionBase { Index getStrides() const { Index r; this->_core->fillStrides(r); return r; } /// @brief Return the total number of elements in the array. - int getNumElements() const { return this->_core->getNumElements(); } + std::size_t getNumElements() const { return this->_core->getNumElements(); } /// @brief Return a view of the array with the order of the dimensions reversed. FullTranspose transpose() const { Index shape = getShape(); Index strides = getStrides(); - for (int n=0; n < ND::value / 2; ++n) { - std::swap(shape[n], shape[ND::value-n-1]); - std::swap(strides[n], strides[ND::value-n-1]); + for (std::size_t n=0; n < static_cast(ND::value / 2); ++n) { + std::swap(shape[n], shape[static_cast(ND::value-n-1)]); + std::swap(strides[n], strides[static_cast(ND::value-n-1)]); } return FullTranspose( getData(), @@ -149,7 +174,7 @@ class ArrayBase : public ExpressionBase { Index newStrides; Index oldShape = getShape(); Index oldStrides = getStrides(); - for (int n=0; n < ND::value; ++n) { + for (std::size_t n=0; n < static_cast(ND::value); ++n) { newShape[n] = oldShape[order[n]]; newStrides[n] = oldStrides[order[n]]; } @@ -159,7 +184,7 @@ class ArrayBase : public ExpressionBase { ); } - /// @brief Return a Array view to this. + /// @brief Return an Array view to this. Shallow const shallow() const { return Shallow(this->getSelf()); } /// @brief Return an ArrayRef view to this. diff --git a/include/ndarray/ArrayBaseN.h.m4 b/include/ndarray/ArrayBaseN.h.m4 index 2d112954..bc2a3cc6 100644 --- a/include/ndarray/ArrayBaseN.h.m4 +++ b/include/ndarray/ArrayBaseN.h.m4 @@ -49,7 +49,7 @@ private: * * @brief Definition of ArrayBaseN, a dimension-specialized CRTP base class for Array and ArrayRef. */ - +#include #include "ndarray/ArrayBase.h" namespace ndarray { @@ -75,12 +75,12 @@ private: ArrayBaseN(Element * data, CorePtr const & core) : Super(data, core) {} }; -SPECIALIZE(1, `int n0', `n0') -SPECIALIZE(2, `int n0, int n1', `n0, n1') -SPECIALIZE(3, `int n0, int n1, int n2', `n0, n1, n2') -SPECIALIZE(4, `int n0, int n1, int n2, int n3', `n0, n1, n2, n3') -SPECIALIZE(5, `int n0, int n1, int n2, int n3, int n4', `n0, n1, n2, n3, n4') -SPECIALIZE(6, `int n0, int n1, int n2, int n3, int n4, int n5', `n0, n1, n2, n3, n4, n5') +SPECIALIZE(1, `std::size_t n0', `n0') +SPECIALIZE(2, `std::size_t n0, std::size_t n1', `n0, n1') +SPECIALIZE(3, `std::size_t n0, std::size_t n1, std::size_t n2', `n0, n1, n2') +SPECIALIZE(4, `std::size_t n0, std::size_t n1, std::size_t n2, std::size_t n3', `n0, n1, n2, n3') +SPECIALIZE(5, `std::size_t n0, std::size_t n1, std::size_t n2, std::size_t n3, std::size_t n4', `n0, n1, n2, n3, n4') +SPECIALIZE(6, `std::size_t n0, std::size_t n1, std::size_t n2, std::size_t n3, std::size_t n4, std::size_t n5', `n0, n1, n2, n3, n4, n5') } // namespace ndarray diff --git a/include/ndarray/ArrayRef.h.m4 b/include/ndarray/ArrayRef.h.m4 index 5a8a4239..39048a6b 100644 --- a/include/ndarray/ArrayRef.h.m4 +++ b/include/ndarray/ArrayRef.h.m4 @@ -82,7 +82,7 @@ public: * * This is implemented in initialization.h. */ - explicit ArrayRef(int n1, int n2=1, int n3=1, int n4=1, int n5=1, int n6=1, int n7=1, int n8=1); + explicit ArrayRef(std::size_t n1, std::size_t n2=1, std::size_t n3=1, std::size_t n4=1, std::size_t n5=1, std::size_t n6=1, std::size_t n7=1, std::size_t n8=1); /** * @brief Non-converting copy constructor. diff --git a/include/ndarray/ArrayTraits.h b/include/ndarray/ArrayTraits.h index af1c9d8f..41b04e1a 100644 --- a/include/ndarray/ArrayTraits.h +++ b/include/ndarray/ArrayTraits.h @@ -17,6 +17,8 @@ * @brief Traits for Array. */ +#include + #include "ndarray_fwd.h" #include "ndarray/ExpressionTraits.h" #include "ndarray/detail/Core.h" @@ -54,7 +56,7 @@ struct ArrayTraits { static Reference makeReference(Element * data, CorePtr const & core) { return Reference(data, core); } - static Iterator makeIterator(Element * data, CorePtr const & core, int stride) { + static Iterator makeIterator(Element * data, CorePtr const & core, std::ptrdiff_t stride) { return Iterator(Reference(data, core), stride); } }; @@ -73,7 +75,7 @@ struct ArrayTraits { static Reference makeReference(Element * data, CorePtr const & core) { return *data; } - static Iterator makeIterator(Element * data, CorePtr const & core, int stride) { + static Iterator makeIterator(Element * data, CorePtr const & core, std::ptrdiff_t stride) { return Iterator(data, stride); } }; @@ -92,7 +94,7 @@ struct ArrayTraits { static Reference makeReference(Element * data, CorePtr const & core) { return *data; } - static Iterator makeIterator(Element * data, CorePtr const & core, int stride) { + static Iterator makeIterator(Element * data, CorePtr const & core, std::ptrdiff_t stride) { return data; } }; @@ -111,7 +113,7 @@ struct ArrayTraits { static Reference makeReference(Element * data, CorePtr const & core) { return *data; } - static Iterator makeIterator(Element * data, CorePtr const & core, int stride) { + static Iterator makeIterator(Element * data, CorePtr const & core, std::ptrdiff_t stride) { return data; } }; diff --git a/include/ndarray/ExpressionBase.h b/include/ndarray/ExpressionBase.h index 934672fc..7d1007ec 100644 --- a/include/ndarray/ExpressionBase.h +++ b/include/ndarray/ExpressionBase.h @@ -11,6 +11,8 @@ #ifndef NDARRAY_ExpressionBase_h_INCLUDED #define NDARRAY_ExpressionBase_h_INCLUDED +#include + /** * @file ndarray/ExpressionBase.h * @@ -50,12 +52,12 @@ class ExpressionBase { /// @brief Nested expression or element value type. typedef typename ExpressionTraits::Value Value; /// @brief Vector type for N-dimensional indices. - typedef Vector Index; + typedef Vector Index; /// @brief CRTP derived type. typedef Derived Self; /// @brief Return a single nested expression or element. - Reference operator[](int n) const { return getSelf().operator[](n); } + Reference operator[](std::size_t n) const { return getSelf().operator[](n); } /// @brief Return the first nested expression or element. Reference front() const { return this->operator[](0); } @@ -70,13 +72,13 @@ class ExpressionBase { Iterator end() const { return getSelf().end(); } /// @brief Return the size of a specific dimension. - template int getSize() const { return getSelf().template getSize

(); } + template std::size_t getSize() const { return getSelf().template getSize

(); } /// @brief Return a Vector of the sizes of all dimensions. Index getShape() const { return getSelf().getShape(); } /// @brief Return the total number of elements in the expression. - int getNumElements() const { return getSelf().getNumElements(); } + std::size_t getNumElements() const { return getSelf().getNumElements(); } /* ------------------------- STL Compatibility -------------------------- */ @@ -86,8 +88,8 @@ class ExpressionBase { typedef Reference reference; typedef Reference const_reference; typedef Iterator pointer; - typedef int difference_type; - typedef int size_type; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; /// @brief Return the size of the first dimension. size_type size() const { return this->template getSize<0>(); } diff --git a/include/ndarray/Manager.h b/include/ndarray/Manager.h index d53ce15a..4c42e8f5 100644 --- a/include/ndarray/Manager.h +++ b/include/ndarray/Manager.h @@ -56,7 +56,7 @@ class SimpleManager : public Manager { typedef typename boost::remove_const::type U; public: - static std::pair allocate(int size) { + static std::pair allocate(std::size_t size) { boost::intrusive_ptr r(new SimpleManager(size)); return std::pair(r, r->_p.get()); } @@ -64,7 +64,7 @@ class SimpleManager : public Manager { virtual bool isUnique() const { return true; } private: - explicit SimpleManager(int size) : _p() { + explicit SimpleManager(std::size_t size) : _p() { if (size > 0) _p.reset(new U[size]); } boost::scoped_array _p; diff --git a/include/ndarray/Vector.h.m4 b/include/ndarray/Vector.h.m4 index bfe94ef0..5167a5c4 100644 --- a/include/ndarray/Vector.h.m4 +++ b/include/ndarray/Vector.h.m4 @@ -67,14 +67,16 @@ define(`VECTOR_TYPEDEFS', typedef boost::reverse_iterator reverse_iterator; typedef boost::reverse_iterator const_reverse_iterator; typedef T * pointer; - typedef int difference_type; - typedef int size_type; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; ')dnl #ifndef NDARRAY_Vector_h_INCLUDED #define NDARRAY_Vector_h_INCLUDED /// @file ndarray/Vector.h Definition for Vector. +#include + #include #include #include @@ -114,7 +116,7 @@ namespace ndarray { * @class Vector * @brief A fixed-size 1D array class. * - * Vector (with T==int) is primarily used as the data + * Vector (with T==std::size_t) is primarily used as the data * type for the shape and strides attributes of Array. * * Vector is implemented almost exactly as a non-aggregate @@ -130,8 +132,8 @@ struct Vector { typedef boost::mpl::int_ ND; - size_type size() const { return N; } ///< @brief Return the size of the Vector. - size_type max_size() const { return N; } ///< @brief Return the size of the Vector. + size_type size() const { return static_cast(N); } ///< @brief Return the size of the Vector. + size_type max_size() const { return static_cast(N); } ///< @brief Return the size of the Vector. bool empty() const { return N==0; } ///< @brief Return true if size() == 0. /// @brief Return an iterator to the beginning of the Vector. iterator begin() { return elems; } @@ -160,9 +162,9 @@ struct Vector { const_reference back() const { return *(elems+N-1); } /// @brief Return a reference to the element with the given index. - reference operator[](int i) { return elems[i]; } + reference operator[](std::size_t i) { return elems[i]; } /// @brief Return a const_reference to the element with the given index. - const_reference operator[](int i) const { return elems[i]; } + const_reference operator[](std::size_t i) const { return elems[i]; } /// @brief Create a new Vector that is a subset of this. template @@ -217,7 +219,11 @@ struct Vector { /// @brief Converting copy constructor. template explicit Vector(Vector const & other) { - this->template operator=(other); + this-> + #ifndef _MSC_VER + template + #endif + operator=(other); } /// @brief Return true if elements of other are equal to the elements of this. @@ -303,9 +309,9 @@ struct Vector { const_reference back() const { NDARRAY_ASSERT(false); return 0; } /// @brief Return a reference to the element with the given index. - reference operator[](int i) { NDARRAY_ASSERT(false); return 0; } + reference operator[](std::size_t i) { NDARRAY_ASSERT(false); return 0; } /// @brief Return a const_reference to the element with the given index. - const_reference operator[](int i) const { NDARRAY_ASSERT(false); return 0; } + const_reference operator[](std::size_t i) const { NDARRAY_ASSERT(false); return 0; } /// @brief Create a new Vector that is a subset of this. template @@ -368,7 +374,7 @@ inline Vector concatenate(Vector const & a, Vector const & b) { std::copy(a.begin(),a.end(),r.begin()); std::copy(b.begin(),b.end(),r.begin()+N); return r; -} +} /// @brief Return a new Vector with the given scalar appended to the original. template @@ -431,4 +437,4 @@ VECTOR_BINARY_OP(>>) } // namespace ndarray -#endif // !NDARRAY_Vector_h_INCLUDED +#endif // !NDARRAY_Vector_h_INCLUDED \ No newline at end of file diff --git a/include/ndarray/bp/Array.h b/include/ndarray/bp/Array.h index c1ce8bf1..aae0ad96 100644 --- a/include/ndarray/bp/Array.h +++ b/include/ndarray/bp/Array.h @@ -10,6 +10,7 @@ */ #ifndef NDARRAY_BP_Array_h_INCLUDED #define NDARRAY_BP_Array_h_INCLUDED +#include #include "boost/numpy.hpp" #include "ndarray.h" @@ -54,12 +55,12 @@ class ToBoostPython< Array > { boost::numpy::dtype dtype = boost::numpy::dtype::get_builtin::type>(); boost::python::object owner = detail::makePyObject(array.getManager()); - int itemsize = dtype.get_itemsize(); - ndarray::Vector shape_elements = array.getShape(); - ndarray::Vector strides_elements = array.getStrides(); + std::size_t itemsize = dtype.get_itemsize(); + ndarray::Vector shape_elements = array.getShape(); + ndarray::Vector strides_elements = array.getStrides(); std::vector shape_bytes(N); std::vector strides_bytes(N); - for (int n=0; n > { if (N != array.get_nd()) return false; if (!boost::is_const::value && !(flags & boost::numpy::ndarray::WRITEABLE)) return false; if (C > 0) { - int requiredStride = sizeof(T); + std::size_t requiredStride = sizeof(T); for (int i = 0; i < C; ++i) { if ((array.shape(N-i-1) > 1) && (array.strides(N-i-1) != requiredStride)) { return false; @@ -93,7 +94,7 @@ class FromBoostPython< Array > { requiredStride *= array.shape(N-i-1); } } else if (C < 0) { - int requiredStride = sizeof(T); + std::size_t requiredStride = sizeof(T); for (int i = 0; i < -C; ++i) { if ((array.shape(i) > 1) && (array.strides(i) != requiredStride)) { return false; @@ -113,7 +114,7 @@ class FromBoostPython< Array > { if (input.is_none()) return Array(); boost::numpy::ndarray array = boost::python::extract(input); boost::numpy::dtype dtype = array.get_dtype(); - int itemsize = dtype.get_itemsize(); + std::size_t itemsize = dtype.get_itemsize(); for (int i = 0; i < N; ++i) { if ((array.shape(i) > 1) && (array.strides(i) % itemsize != 0)) { PyErr_SetString( @@ -127,14 +128,14 @@ class FromBoostPython< Array > { if (obj_owner.is_none()) { obj_owner = array; } - Vector shape; - Vector strides; + Vector shape; + Vector strides; for (int i=0; i 1) { strides[i] = array.strides(i) / itemsize; } else { - strides[i] = 1.0; + strides[i] = 1; } } Array r = ndarray::external( diff --git a/include/ndarray/bp/Vector.h b/include/ndarray/bp/Vector.h index bc86e278..3e3d2c57 100644 --- a/include/ndarray/bp/Vector.h +++ b/include/ndarray/bp/Vector.h @@ -10,7 +10,7 @@ */ #ifndef NDARRAY_BP_Vector_h_INCLUDED #define NDARRAY_BP_Vector_h_INCLUDED - +#include #include "boost/python.hpp" #include "ndarray/Vector.h" #include "ndarray/bp_fwd.h" @@ -26,7 +26,7 @@ class ToBoostPython< Vector > { static boost::python::tuple apply(Vector const & x) { boost::python::handle<> t(PyTuple_New(N)); for (int n=0; n(n)]); Py_INCREF(item.ptr()); PyTuple_SET_ITEM(t.get(), n, item.ptr()); } @@ -62,7 +62,7 @@ class FromBoostPython< Vector > { } Vector r; for (int n=0; n(t[n]); + r[static_cast(n)] = boost::python::extract(t[n]); } return r; } @@ -72,4 +72,4 @@ class FromBoostPython< Vector > { } // namespace ndarray -#endif // !NDARRAY_BP_Vector_h_INCLUDED +#endif // !NDARRAY_BP_Vector_h_INCLUDED \ No newline at end of file diff --git a/include/ndarray/casts.h b/include/ndarray/casts.h index bb1d4dc6..ed9ec90d 100644 --- a/include/ndarray/casts.h +++ b/include/ndarray/casts.h @@ -16,7 +16,8 @@ * * @brief Specialized casts for Array. */ - +#include + #include "ndarray/Array.h" #include "ndarray/ArrayRef.h" #include @@ -39,9 +40,9 @@ struct ComplexExtractor { >::type RealElement; typedef ArrayRef Result; typedef detail::ArrayAccess Access; - typedef Vector Index; + typedef Vector Index; - static inline Result apply(Array_ const & array, int offset) { + static inline Result apply(Array_ const & array, std::size_t offset) { return Access::construct( reinterpret_cast(array.getData()) + offset, Access::Core::create(array.getShape(), array.getStrides() * 2, array.getManager()) @@ -90,17 +91,17 @@ static_dimension_cast(Array const & array) { template Array dynamic_dimension_cast(Array const & array) { - Vector shape = array.getShape(); - Vector strides = array.getStrides(); + Vector shape = array.getShape(); + Vector strides = array.getStrides(); if (C_ >= 0) { - int n = 1; + std::size_t n = 1; for (int i=1; i <= C_; ++i) { - if (strides[N-i] != n) return Array(); + if (strides[static_cast(N-i)] != n) return Array(); n *= shape[N-i]; } } else { - int n = 1; - for (int i=0; i < -C_; ++i) { + std::size_t n = 1; + for (std::size_t i=0; i < static_cast(-C_); ++i) { if (strides[i] != n) return Array(); n *= strides[i]; } @@ -138,12 +139,12 @@ flatten(Array const & input) { typedef detail::ArrayAccess< ArrayRef > Access; typedef typename Access::Core Core; BOOST_STATIC_ASSERT(C+Nf-N >= 1); - Vector oldShape = input.getShape(); - Vector newShape = oldShape.template first(); - for (int n=Nf; n oldShape = input.getShape(); + Vector newShape = oldShape.template first(); + for (std::size_t n=static_cast(Nf); n(N); ++n) newShape[Nf-1] *= oldShape[n]; - Vector newStrides = input.getStrides().template first(); - newStrides[Nf-1] = 1; + Vector newStrides = input.getStrides().template first(); + newStrides[static_cast(Nf-1)] = 1; return Access::construct(input.getData(), Core::create(newShape, newStrides, input.getManager())); } diff --git a/include/ndarray/detail/BinaryOp.h b/include/ndarray/detail/BinaryOp.h index 36ec2160..e0ec7cf3 100644 --- a/include/ndarray/detail/BinaryOp.h +++ b/include/ndarray/detail/BinaryOp.h @@ -16,6 +16,7 @@ * * @brief Lazy binary expression templates. */ +#include #include "ndarray/ExpressionBase.h" #include "ndarray/vectorize.h" @@ -96,7 +97,7 @@ class BinaryOpExpression : public ExpressionBase< BinaryOpExpression::Iterator Iterator; typedef typename ExpressionTraits::Value Value; typedef typename ExpressionTraits::Reference Reference; - typedef Vector Index; + typedef Vector Index; BinaryOpExpression( Operand1 const & operand1, @@ -107,7 +108,7 @@ class BinaryOpExpression : public ExpressionBase< BinaryOpExpression int getSize() const { + template std::size_t getSize() const { return _operand1.template getSize

(); } diff --git a/include/ndarray/detail/Core.h b/include/ndarray/detail/Core.h index 4c603b2c..c3dd3edb 100644 --- a/include/ndarray/detail/Core.h +++ b/include/ndarray/detail/Core.h @@ -17,6 +17,8 @@ * @brief Definitions for Core. */ +#include + #include #include #include "ndarray/Vector.h" @@ -54,8 +56,8 @@ class Core : public Core { /// @brief Create a Core::Ptr with the given shape, strides, and manager. template static Ptr create( - Vector const & shape, - Vector const & strides, + Vector const & shape, + Vector const & strides, Manager::Ptr const & manager = Manager::Ptr() ) { return Ptr(new Core(shape, strides, manager), false); @@ -64,7 +66,7 @@ class Core : public Core { /// @brief Create a Core::Ptr with the given shape and manager with contiguous strides. template static Ptr create( - Vector const & shape, + Vector const & shape, DataOrderEnum order, Manager::Ptr const & manager = Manager::Ptr() ) { @@ -85,39 +87,39 @@ class Core : public Core { Ptr copy() const { return Ptr(new Core(*this)); } /// @brief Return the size of the Nth dimension. - int getSize() const { return _size; } + std::size_t getSize() const { return _size; } /// @brief Return the stride of the Nth dimension. - int getStride() const { return _stride; } + std::size_t getStride() const { return _stride; } /// @brief Set the size of the Nth dimension. - void setSize(int size) { _size = size; } + void setSize(std::size_t size) { _size = size; } /// @brief Set the stride of the Nth dimension. - void setStride(int stride) { _stride = stride; } + void setStride(std::size_t stride) { _stride = stride; } /// @brief Recursively compute the offset to an element. template - int computeOffset(Vector const & index) const { + std::size_t computeOffset(Vector const & index) const { return index[M-N] * this->getStride() + Super::computeOffset(index); } /// @brief Recursively fill a shape vector. template - void fillShape(Vector & shape) const { + void fillShape(Vector & shape) const { shape[M-N] = this->getSize(); Super::fillShape(shape); } /// @brief Recursively fill a strides vector. template - void fillStrides(Vector & strides) const { + void fillStrides(Vector & strides) const { strides[M-N] = this->getStride(); Super::fillStrides(strides); } /// @brief Recursively determine the total number of elements. - int getNumElements() const { + std::size_t getNumElements() const { return getSize() * Super::getNumElements(); } @@ -126,23 +128,23 @@ class Core : public Core { // Explicit strides template Core ( - Vector const & shape, - Vector const & strides, + Vector const & shape, + Vector const & strides, Manager::Ptr const & manager ) : Super(shape, strides, manager), _size(shape[M-N]), _stride(strides[M-N]) {} // Row-major strides template Core ( - Vector const & shape, + Vector const & shape, Manager::Ptr const & manager ) : Super(shape, manager), _size(shape[M-N]), _stride(Super::getStride() * Super::getSize()) {} // Column-major strides template Core ( - Vector const & shape, - int stride, + Vector const & shape, + std::size_t stride, Manager::Ptr const & manager ) : Super(shape, stride * shape[M-N], manager), _size(shape[M-N]), _stride(stride) {} @@ -154,8 +156,8 @@ class Core : public Core { Core(Core const & other) : Super(other), _size(other._size), _stride(other._stride) {} private: - int _size; - int _stride; + std::size_t _size; + std::size_t _stride; }; /** @@ -184,12 +186,12 @@ class Core<0> { Ptr copy() const { return Ptr(new Core(*this)); } - int getSize() const { return 1; } - int getStride() const { return 1; } + std::size_t getSize() const { return 1; } + std::size_t getStride() const { return 1; } /// @brief Recursively compute the offset to an element. template - int computeOffset(Vector const & index) const { return 0; } + std::size_t computeOffset(Vector const & index) const { return 0; } /// @brief Return the Manager that determines the lifetime of the array data. Manager::Ptr getManager() const { return _manager; } @@ -199,14 +201,14 @@ class Core<0> { /// @brief Recursively fill a shape vector. template - void fillShape(Vector const & shape) const {} + void fillShape(Vector const & shape) const {} /// @brief Recursively fill a strides vector. template - void fillStrides(Vector const & strides) const {} + void fillStrides(Vector const & strides) const {} /// @brief Recursively determine the total number of elements. - int getNumElements() const { return 1; } + std::size_t getNumElements() const { return 1; } /// @brief Return the reference count (for debugging purposes). int getRC() const { return _rc; } @@ -220,21 +222,21 @@ class Core<0> { template Core( - Vector const & shape, - Vector const & strides, + Vector const & shape, + Vector const & strides, Manager::Ptr const & manager ) : _manager(manager), _rc(1) {} template Core( - Vector const & shape, + Vector const & shape, Manager::Ptr const & manager ) : _manager(manager), _rc(1) {} template Core( - Vector const & shape, - int stride, + Vector const & shape, + std::size_t stride, Manager::Ptr const & manager ) : _manager(manager), _rc(1) {} @@ -271,4 +273,4 @@ getDimension(typename Core::Ptr const & core) { return core; } } // namespace detail } // namespace ndarray -#endif // !NDARRAY_DETAIL_Core_h_INCLUDED +#endif // !NDARRAY_DETAIL_Core_h_INCLUDED \ No newline at end of file diff --git a/include/ndarray/detail/NestedIterator.h b/include/ndarray/detail/NestedIterator.h index 7e6766d4..7a959b4c 100644 --- a/include/ndarray/detail/NestedIterator.h +++ b/include/ndarray/detail/NestedIterator.h @@ -48,7 +48,7 @@ class NestedIterator : public boost::iterator_facade< typedef typename ArrayTraits::Value Value; typedef typename ArrayTraits::Reference Reference; - Reference operator[](int n) const { + Reference operator[](std::size_t n) const { Reference r(_ref); r._data += n * _stride; return r; @@ -60,7 +60,7 @@ class NestedIterator : public boost::iterator_facade< NestedIterator() : _ref(Value()), _stride(0) {} - NestedIterator(Reference const & ref, int stride) : _ref(ref), _stride(stride) {} + NestedIterator(Reference const & ref, std::ptrdiff_t stride) : _ref(ref), _stride(stride) {} NestedIterator(NestedIterator const & other) : _ref(other._ref), _stride(other._stride) {} @@ -94,10 +94,10 @@ class NestedIterator : public boost::iterator_facade< void increment() { _ref._data += _stride; } void decrement() { _ref._data -= _stride; } - void advance(int n) { _ref._data += _stride * n; } + void advance(std::ptrdiff_t n) { _ref._data += _stride * n; } template - int distance_to(NestedIterator const & other) const { + std::ptrdiff_t distance_to(NestedIterator const & other) const { return std::distance(_ref._data, other._ref._data) / _stride; } @@ -107,7 +107,7 @@ class NestedIterator : public boost::iterator_facade< } Reference _ref; - int _stride; + std::ptrdiff_t _stride; }; } // namespace detail diff --git a/include/ndarray/detail/StridedIterator.h b/include/ndarray/detail/StridedIterator.h index 17855c40..385d3cbb 100644 --- a/include/ndarray/detail/StridedIterator.h +++ b/include/ndarray/detail/StridedIterator.h @@ -16,7 +16,8 @@ * * @brief Definition of StridedIterator. */ - +#include + #include "ndarray_fwd.h" #include @@ -40,7 +41,7 @@ class StridedIterator : public boost::iterator_facade< StridedIterator() : _data(0), _stride(0) {} - StridedIterator(T * data, int stride) : _data(data), _stride(stride) {} + StridedIterator(T * data, std::ptrdiff_t stride) : _data(data), _stride(stride) {} StridedIterator(StridedIterator const & other) : _data(other._data), _stride(other._stride) {} @@ -75,10 +76,10 @@ class StridedIterator : public boost::iterator_facade< void increment() { _data += _stride; } void decrement() { _data -= _stride; } - void advance(int n) { _data += _stride * n; } + void advance(std::ptrdiff_t n) { _data += _stride * n; } template - int distance_to(StridedIterator const & other) const { + std::ptrdiff_t distance_to(StridedIterator const & other) const { return std::distance(_data, other._data) / _stride; } @@ -88,7 +89,7 @@ class StridedIterator : public boost::iterator_facade< } T * _data; - int _stride; + std::ptrdiff_t _stride; }; diff --git a/include/ndarray/detail/UnaryOp.h b/include/ndarray/detail/UnaryOp.h index ef7737a1..37c5802b 100644 --- a/include/ndarray/detail/UnaryOp.h +++ b/include/ndarray/detail/UnaryOp.h @@ -16,7 +16,8 @@ * * @brief Lazy unary expression templates. */ - +#include + #include "ndarray/ExpressionBase.h" #include "ndarray/vectorize.h" #include @@ -79,12 +80,12 @@ class UnaryOpExpression : public ExpressionBase< UnaryOpExpression::Iterator Iterator; typedef typename ExpressionTraits::Value Value; typedef typename ExpressionTraits::Reference Reference; - typedef Vector Index; + typedef Vector Index; UnaryOpExpression(Operand const & operand, UnaryFunction const & functor) : _operand(operand), _functor(functor) {} - Reference operator[](int n) const { + Reference operator[](std::size_t n) const { return Reference(_operand[n],_functor); } @@ -96,7 +97,7 @@ class UnaryOpExpression : public ExpressionBase< UnaryOpExpression int getSize() const { + template std::size_t getSize() const { return _operand.template getSize

(); } diff --git a/include/ndarray/fft/FourierOps.h b/include/ndarray/fft/FourierOps.h index 1cdcd79a..c02a04dc 100644 --- a/include/ndarray/fft/FourierOps.h +++ b/include/ndarray/fft/FourierOps.h @@ -11,7 +11,7 @@ #ifndef NDARRAY_FFT_FourierOps_h_INCLUDED #define NDARRAY_FFT_FourierOps_h_INCLUDED -/** +/** * @file ndarray/fft/FourierOps.h * * @brief Common Fourier-space operations. @@ -21,10 +21,17 @@ #include "ndarray.h" + + namespace ndarray { /// \cond INTERNAL namespace detail { +#ifdef _MSC_VER +/** Portable double pi value. */ +static const double M_PI = 4. * atan(1.); +#endif + /** * @internal @ingroup FFTndarrayInternalGroup * @brief Implementations for the shift() and differentiate() functions. @@ -43,7 +50,7 @@ struct FourierOps { T u = -2.0 * M_PI * (*offset) / array.size(); int kMid = (array.size() + 1) / 2; for (int k = 0; k < kMid; ++k, ++iter) { - FourierOps::shift(offset+1, factor * std::polar(static_cast(1), u * k), + FourierOps::shift(offset+1, factor * std::polar(static_cast(1), u * k), *iter, real_last_dim); } if (array.size() % 2 == 0) { @@ -85,7 +92,7 @@ struct FourierOps { */ template struct FourierOps { - + template static void shift( T const * offset, @@ -117,7 +124,7 @@ struct FourierOps { } if (real_last_dim % 2 == 0) { array[kMid] = static_cast(0); - } + } } }; diff --git a/include/ndarray/fft/FourierTransform.cc b/include/ndarray/fft/FourierTransform.cc index 2aefac42..89c0176c 100644 --- a/include/ndarray/fft/FourierTransform.cc +++ b/include/ndarray/fft/FourierTransform.cc @@ -8,34 +8,47 @@ * of the source distribution, or alternately available at: * https://github.com/ndarray/ndarray */ +#include +#include +#include #include "ndarray/fft/FFTWTraits.h" #include "ndarray/fft/FourierTransform.h" namespace ndarray { -template +template template Array::ElementX,M,M> -FourierTransform::initializeX(Vector const & shape) { - OwnerX xOwner = detail::FFTWTraits::allocateX(shape.product()); +FourierTransform::initializeX(Vector const & shape) { + if (shape.product() > std::numeric_limits::max()) { + // fftw3 only supports int many elements. + throw std::exception(); + } + OwnerX xOwner = detail::FFTWTraits::allocateX(static_cast(shape.product())); + if (xOwner.get() == nullptr) throw std::exception(); return Array(external(xOwner.get(), shape, ROW_MAJOR, xOwner)); } -template +template template Array::ElementK,M,M> -FourierTransform::initializeK(Vector const & shape) { - Vector kShape(shape); +FourierTransform::initializeK(Vector const & shape) { + Vector kShape(shape); kShape[M-1] = detail::FourierTraits::computeLastDimensionSize(shape[M-1]); - OwnerK kOwner = detail::FFTWTraits::allocateK(kShape.product()); + if (kShape.product() > std::numeric_limits::max()) { + // fftw3 only supports int many elements. + throw std::exception(); + } + OwnerK kOwner = detail::FFTWTraits::allocateK(static_cast(kShape.product())); + if (kOwner.get() == nullptr) throw std::exception(); return Array(external(kOwner.get(), kShape, ROW_MAJOR, kOwner)); } -template +template template void FourierTransform::initialize( - Vector const & shape, + Vector const & shape, Array & x, Array & k ) { @@ -45,22 +58,25 @@ FourierTransform::initialize( NDARRAY_ASSERT(std::equal(shape.begin(), shape.end()-1, k.getShape().begin())); } -template +template typename FourierTransform::Ptr FourierTransform::planForward( - Index const & shape, + Index const & shape, typename FourierTransform::ArrayX & x, typename FourierTransform::ArrayK & k ) { initialize(shape,x,k); - return Ptr( - new FourierTransform( - detail::FFTWTraits::forward( - N, shape.begin(), 1, + auto ftshape = ndarray::Vector(shape); + void *fp = detail::FFTWTraits::forward( + N, ftshape.begin(), 1, x.getData(), NULL, 1, 0, k.getData(), NULL, 1, 0, - FFTW_MEASURE | FFTW_DESTROY_INPUT - ), + FFTW_MEASURE | FFTW_DESTROY_INPUT); + if (fp == nullptr) + throw std::exception(); + return Ptr( + new FourierTransform( + fp, x.getManager(), k.getManager() ) @@ -75,10 +91,11 @@ FourierTransform::planInverse( typename FourierTransform::ArrayX & x ) { initialize(shape,x,k); + auto ftshape = ndarray::Vector(shape); return Ptr( new FourierTransform( detail::FFTWTraits::inverse( - N, shape.begin(), 1, + N, ftshape.begin(), 1, k.getData(), NULL, 1, 0, x.getData(), NULL, 1, 0, FFTW_MEASURE | FFTW_DESTROY_INPUT @@ -97,21 +114,24 @@ FourierTransform::planMultiplexForward( typename FourierTransform::MultiplexArrayK & k ) { initialize(shape,x,k); - return Ptr( - new FourierTransform( - detail::FFTWTraits::forward( - N, shape.begin()+1, shape[0], + auto ftshape = ndarray::Vector(shape); + void *fp = detail::FFTWTraits::forward( + N, ftshape.begin()+1, ftshape[0], x.getData(), NULL, 1, x.template getStride<0>(), k.getData(), NULL, 1, k.template getStride<0>(), - FFTW_MEASURE | FFTW_DESTROY_INPUT - ), + FFTW_MEASURE | FFTW_DESTROY_INPUT); + if (fp == nullptr) + throw std::exception(); + return Ptr( + new FourierTransform( + fp, x.getManager(), k.getManager() ) ); } -template +template typename FourierTransform::Ptr FourierTransform::planMultiplexInverse( MultiplexIndex const & shape, @@ -119,10 +139,11 @@ FourierTransform::planMultiplexInverse( typename FourierTransform::MultiplexArrayX & x ) { initialize(shape,x,k); + auto ftshape = ndarray::Vector(shape); return Ptr( new FourierTransform( detail::FFTWTraits::inverse( - N, shape.begin()+1, shape[0], + N, ftshape.begin()+1, ftshape[0], k.getData(), NULL, 1, k.template getStride<0>(), x.getData(), NULL, 1, x.template getStride<0>(), FFTW_MEASURE | FFTW_DESTROY_INPUT diff --git a/include/ndarray/fft/FourierTransform.h b/include/ndarray/fft/FourierTransform.h index ba87a115..afd0059e 100644 --- a/include/ndarray/fft/FourierTransform.h +++ b/include/ndarray/fft/FourierTransform.h @@ -11,12 +11,14 @@ #ifndef NDARRAY_FFT_FourierTransform_h_INCLUDED #define NDARRAY_FFT_FourierTransform_h_INCLUDED -/** +/** * @file ndarray/fft/FourierTransform.h * * @brief Definitions for FourierTransform. */ +#include + #include #include "ndarray.h" @@ -42,22 +44,22 @@ template class FourierTransform : private boost::noncopyable { BOOST_STATIC_ASSERT((!boost::is_const::value)); public: - + typedef boost::shared_ptr Ptr; typedef typename detail::FourierTraits::ElementX ElementX; ///< Real-space array data type; typedef typename detail::FourierTraits::ElementK ElementK; ///< Fourier-space array data type; - typedef Vector Index; ///< Shape type for arrays. + typedef Vector Index; ///< Shape type for arrays. typedef Array ArrayX; ///< Real-space array type. typedef Array ArrayK; ///< Fourier-space array type. - typedef Vector MultiplexIndex; ///< Shape type for multiplexed arrays. + typedef Vector MultiplexIndex; ///< Shape type for multiplexed arrays. typedef Array MultiplexArrayX; ///< Real-space multiplexed array type. typedef Array MultiplexArrayK; ///< Fourier-space multiplexed array type. /** * @brief Create a plan for forward-transforming a single N-dimensional array. - * + * * Arrays will be initialized with new memory if empty. If they are not empty, * existing data may be overwritten when the plan is created. */ @@ -69,7 +71,7 @@ class FourierTransform : private boost::noncopyable { /** * @brief Create a plan for inverse-transforming a single N-dimensional array. - * + * * Arrays will be initialized with new memory if empty. If they are not empty, * existing data may be overwritten when the plan is created. */ @@ -81,7 +83,7 @@ class FourierTransform : private boost::noncopyable { /** * @brief Create a plan for forward-transforming a sequence of nested N-dimensional arrays. - * + * * Arrays will be initialized with new memory if empty. If they are not empty, * existing data may be overwritten when the plan is created. */ @@ -93,7 +95,7 @@ class FourierTransform : private boost::noncopyable { /** * @brief Create a plan for inverse-transforming a sequence of nested N-dimensional arrays. - * + * * Arrays will be initialized with new memory if empty. If they are not empty, * existing data may be overwritten when the plan is created. */ @@ -105,26 +107,26 @@ class FourierTransform : private boost::noncopyable { /// @brief Create a new real-space array with the given real-space shape. template - static Array initializeX(Vector const & shape); + static Array initializeX(Vector const & shape); /// @brief Create a new Fourier-space array with the given real-space shape. template - static Array initializeK(Vector const & shape); + static Array initializeK(Vector const & shape); - /** + /** * @brief Initialize, as necessary, a pair of arrays with the given real-space shape. - * + * * If either array is not empty, it must be consistent with the given shape. */ template - static void initialize(Vector const & shape, Array & x, Array & k); + static void initialize(Vector const & shape, Array & x, Array & k); /// @brief Execute the FFTW plan. void execute(); ~FourierTransform(); -private: + private: typedef boost::shared_ptr OwnerX; typedef boost::shared_ptr OwnerK; diff --git a/include/ndarray/initialization.h b/include/ndarray/initialization.h index a787aa0a..721ed15d 100644 --- a/include/ndarray/initialization.h +++ b/include/ndarray/initialization.h @@ -14,7 +14,7 @@ /** * \file ndarray/initialization.h @brief Construction functions for array. */ - +#include #include "ndarray/Array.h" #include "ndarray/ArrayRef.h" #include "ndarray/Manager.h" @@ -50,15 +50,15 @@ class SimpleInitializer : public Initializer< N, SimpleInitializer > { typedef typename Access::Core Core; typedef typename Access::Element Element; DataOrderEnum order = (ExpressionTraits< Target >::RMC::value < 0) ? COLUMN_MAJOR : ROW_MAJOR; - int total = _shape.product(); + std::size_t total = _shape.product(); std::pair p = SimpleManager::allocate(total); return Access::construct(p.second, Core::create(_shape, order, p.first)); } - explicit SimpleInitializer(Vector const & shape) : _shape(shape) {} + explicit SimpleInitializer(Vector const & shape) : _shape(shape) {} private: - Vector _shape; + Vector _shape; }; template @@ -79,16 +79,16 @@ class ExternalInitializer : public Initializer< N, ExternalInitializer const & shape, - Vector const & strides, + Vector const & shape, + Vector const & strides, Owner const & owner ) : _data(data), _owner(owner), _shape(shape), _strides(strides) {} private: T * _data; Owner _owner; - Vector _shape; - Vector _strides; + Vector _shape; + Vector _strides; }; } // namespace detail @@ -102,7 +102,7 @@ class ExternalInitializer : public Initializer< N, ExternalInitializer -inline detail::SimpleInitializer allocate(Vector const & shape) { +inline detail::SimpleInitializer allocate(Vector const & shape) { return detail::SimpleInitializer(shape); } @@ -111,7 +111,7 @@ inline detail::SimpleInitializer allocate(Vector const & shape) { * * @returns A temporary object convertible to an Array with fully contiguous row-major strides. */ -inline detail::SimpleInitializer<1> allocate(int n) { +inline detail::SimpleInitializer<1> allocate(std::size_t n) { return detail::SimpleInitializer<1>(ndarray::makeVector(n)); } @@ -120,7 +120,7 @@ inline detail::SimpleInitializer<1> allocate(int n) { * * @returns A temporary object convertible to an Array with fully contiguous row-major strides. */ -inline detail::SimpleInitializer<2> allocate(int n1, int n2) { +inline detail::SimpleInitializer<2> allocate(std::size_t n1, std::size_t n2) { return detail::SimpleInitializer<2>(ndarray::makeVector(n1, n2)); } @@ -129,7 +129,7 @@ inline detail::SimpleInitializer<2> allocate(int n1, int n2) { * * @returns A temporary object convertible to an Array with fully contiguous row-major strides. */ -inline detail::SimpleInitializer<3> allocate(int n1, int n2, int n3) { +inline detail::SimpleInitializer<3> allocate(std::size_t n1, std::size_t n2, std::size_t n3) { return detail::SimpleInitializer<3>(ndarray::makeVector(n1, n2, n3)); } @@ -150,12 +150,12 @@ copy(ExpressionBase const & expr) { /// @brief Compute row- or column-major strides for the given shape. template -Vector computeStrides(Vector const & shape, DataOrderEnum order=ROW_MAJOR) { - Vector r(1); +Vector computeStrides(Vector const & shape, DataOrderEnum order=ROW_MAJOR) { + Vector r(1); if (order == ROW_MAJOR) { - for (int n=N-1; n > 0; --n) r[n-1] = r[n] * shape[n]; + for (std::size_t n=static_cast(N-1); n > 0; --n) r[n-1] = r[n] * shape[n]; } else { - for (int n=1; n < N; ++n) r[n] = r[n-1] * shape[n-1]; + for (std::size_t n=1; n < static_cast(N); ++n) r[n] = r[n-1] * shape[n-1]; } return r; } @@ -176,8 +176,8 @@ Vector computeStrides(Vector const & shape, DataOrderEnum order=RO template inline detail::ExternalInitializer external( T * data, - Vector const & shape, - Vector const & strides, + Vector const & shape, + Vector const & strides, Owner const & owner ) { return detail::ExternalInitializer(data, shape, strides, owner); @@ -198,8 +198,8 @@ inline detail::ExternalInitializer external( template inline detail::ExternalInitializer external( T * data, - Vector const & shape, - Vector const & strides + Vector const & shape, + Vector const & strides ) { return detail::ExternalInitializer(data, shape, strides, detail::NullOwner()); } @@ -220,7 +220,7 @@ inline detail::ExternalInitializer external( template inline detail::ExternalInitializer external( T * data, - Vector const & shape, + Vector const & shape, DataOrderEnum order, Owner const & owner ) { @@ -242,7 +242,7 @@ inline detail::ExternalInitializer external( template inline detail::ExternalInitializer external( T * data, - Vector const & shape, + Vector const & shape, DataOrderEnum order = ROW_MAJOR ) { return detail::ExternalInitializer( @@ -253,7 +253,7 @@ inline detail::ExternalInitializer external( /// @} template -Array::Array(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8) +Array::Array(std::size_t n1, std::size_t n2, std::size_t n3, std::size_t n4, std::size_t n5, std::size_t n6, std::size_t n7, std::size_t n8) : Super(0, CorePtr()) { typename Super::Index shape; @@ -269,7 +269,7 @@ Array::Array(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int } template -ArrayRef::ArrayRef(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8) +ArrayRef::ArrayRef(std::size_t n1, std::size_t n2, std::size_t n3, std::size_t n4, std::size_t n5, std::size_t n6, std::size_t n7, std::size_t n8) : Super(Array(n1, n2, n3, n4, n5, n6, n7, n8)) {} diff --git a/include/ndarray/swig/PyConverter.h b/include/ndarray/swig/PyConverter.h index 236b6264..df22dba6 100644 --- a/include/ndarray/swig/PyConverter.h +++ b/include/ndarray/swig/PyConverter.h @@ -15,6 +15,7 @@ * @file ndarray/swig/PyConverter.h * @brief Python C-API conversions for standard numeric types. */ +#include #include #include @@ -44,11 +45,11 @@ namespace detail { */ template struct PyConverterBase { - + /** * @brief Check if a Python object might be convertible to T. * - * \return true if the conversion may be successful, and + * \return true if the conversion may be successful, and * false if it definitely is not. Will not raise a Python * exception. * @@ -90,7 +91,7 @@ struct PyConverterBase { if (!PyConverter::fromPythonStage1(p)) return false; return PyConverter::fromPythonStage2(arg,*output); } - + }; } // namespace ndarray::detail @@ -105,7 +106,7 @@ struct PyConverterBase { template struct PyConverter : public detail::PyConverterBase { - /** + /** * @brief Convert a C++ object to a new Python object. * * \return A new Python object, or NULL on failure (with @@ -180,6 +181,43 @@ struct PyConverter : public detail::PyConverterBase { static PyTypeObject const * getPyType() { return &PyBool_Type; } }; +template <> +struct PyConverter : public detail::PyConverterBase { + + static bool fromPythonStage1(PyPtr & input) { + if (!PyInt_Check(input.get()) && !PyLong_Check(input.get())) { + PyPtr s(PyObject_Repr(input.get())); + if (!s) return false; + char * cs = PyString_AsString(s.get()); + if (!cs) return false; + PyErr_Format(PyExc_TypeError,"'%s' is not a valid C++ size value.",cs); + } + return true; + } + + static bool fromPythonStage2(PyPtr const & input, std::size_t & output) { + NDARRAY_ASSERT(input); + long long tmpoutput = PyLong_AsLongLong(input.get()); + if (tmpoutput < 0) { + return false; + } else { + switch(sizeof(std::size_t)) { + case 4: output = PyLong_AsLong(input.get()); break; + case 8: output = PyLong_AsLongLong(input.get()); break; + // no datatype here... + default: throw std::exception(); + } + } + return true; + } + + static PyObject * toPython(std::size_t input) { + return PyLong_FromSize_t(input); + } + + static PyTypeObject const * getPyType() { return &PyLong_Type; } +}; + template <> struct PyConverter : public detail::PyConverterBase { @@ -203,7 +241,7 @@ struct PyConverter : public detail::PyConverterBase { static PyObject * toPython(int input) { return PyInt_FromLong(input); } - + static PyTypeObject const * getPyType() { return &PyInt_Type; } }; @@ -257,7 +295,7 @@ struct PyConverter : public detail::PyConverterBase { static PyObject * toPython(float input) { return PyFloat_FromDouble(input); } - + static PyTypeObject const * getPyType() { return &PyFloat_Type; } }; @@ -284,7 +322,7 @@ struct PyConverter : public detail::PyConverterBase { static PyObject * toPython(double input) { return PyFloat_FromDouble(input); } - + static PyTypeObject const * getPyType() { return &PyFloat_Type; } }; @@ -312,7 +350,7 @@ struct PyConverter< std::complex > : public detail::PyConverterBase< std::com static PyObject * toPython(std::complex const & input) { return PyComplex_FromDoubles(input.real(),input.imag()); } - + static PyTypeObject const * getPyType() { return &PyComplex_Type; } }; @@ -342,7 +380,7 @@ struct PyConverter< std::string > : public detail::PyConverterBase static PyObject * toPython(std::string const & input) { return PyString_FromStringAndSize(input.data(),input.size()); } - + static PyTypeObject const * getPyType() { return &PyString_Type; } }; diff --git a/include/ndarray/swig/numpy.h b/include/ndarray/swig/numpy.h index a6b80a1d..5f0e2ce9 100644 --- a/include/ndarray/swig/numpy.h +++ b/include/ndarray/swig/numpy.h @@ -11,27 +11,28 @@ #ifndef NDARRAY_SWIG_numpy_h_INCLUDED #define NDARRAY_SWIG_numpy_h_INCLUDED -/** +/** * @file ndarray/swig/numpy.h * @brief Python C-API conversions between ndarray and numpy. */ - +#include +#include #include "ndarray.h" #include "ndarray/swig/PyConverter.h" namespace ndarray { namespace detail { -/** +/** * @internal @ingroup ndarrayPythonInternalGroup - * @brief Traits class that specifies Numpy typecodes for numeric types. + * @brief Traits class that specifies Numpy typecodes for numeric types. */ -template struct NumpyTraits { - static int getCode(); +template struct NumpyTraits { + static int getCode(); }; /// \cond SPECIALIZATIONS - + template <> struct NumpyTraits { static int getCode() { if (sizeof(bool)==sizeof(npy_bool)) return NPY_BOOL; @@ -47,37 +48,68 @@ template <> struct NumpyTraits { static int getCode() { return NPY_UB template <> struct NumpyTraits { static int getCode() { return NPY_BYTE; } }; template <> struct NumpyTraits { static int getCode() { return NPY_USHORT; } }; template <> struct NumpyTraits { static int getCode() { return NPY_SHORT; } }; -template <> struct NumpyTraits { static int getCode() { return NPY_UINT; } }; -template <> struct NumpyTraits { static int getCode() { return NPY_INT; } }; +// NPY_INT is on Windows a virtual flag that is never actually used. It must be +// checked against the platform dtype. +// see http://mail.scipy.org/pipermail/numpy-discussion/2010-June/051057.html. +template <> struct NumpyTraits { static int getCode() { +#ifdef _MSC_VER + switch(sizeof(int)) { + case 1: return NPY_UBYTE; + case 2: return NPY_USHORT; + case 4: return NPY_ULONG; + case 8: return NPY_ULONGLONG; + // no datatype here... + default: throw std::exception(); + } +#else + return NPY_UINT; +#endif +}}; +template <> struct NumpyTraits { static int getCode() { +#ifdef _MSC_VER + switch(sizeof(int)) { + case 1: return NPY_BYTE; + case 2: return NPY_SHORT; + case 4: return NPY_LONG; + case 8: return NPY_LONGLONG; + // no datatype here... + default: throw std::exception(); + } +#else + return NPY_INT; +#endif +}}; template <> struct NumpyTraits { static int getCode() { return NPY_ULONG; } }; template <> struct NumpyTraits { static int getCode() { return NPY_LONG; } }; template <> struct NumpyTraits { static int getCode() { return NPY_ULONGLONG; } }; template <> struct NumpyTraits { static int getCode() { return NPY_LONGLONG; } }; template <> struct NumpyTraits { static int getCode() { return NPY_FLOAT; } }; template <> struct NumpyTraits { static int getCode() { return NPY_DOUBLE; } }; -template <> struct NumpyTraits { static int getCode() { return NPY_LONGDOUBLE; } }; +#if (npy_double != npy_longdouble) + template <> struct NumpyTraits { static int getCode() { return NPY_LONGDOUBLE; } }; +#endif template <> struct NumpyTraits { static int getCode() { return NPY_CFLOAT; } }; template <> struct NumpyTraits { static int getCode() { return NPY_CDOUBLE; } }; template <> struct NumpyTraits { static int getCode() { return NPY_CLONGDOUBLE; } }; -template <> struct NumpyTraits > { - static int getCode() { assert(sizeof(std::complex)==sizeof(npy_cfloat)); return NPY_CFLOAT; } +template <> struct NumpyTraits > { + static int getCode() { assert(sizeof(std::complex)==sizeof(npy_cfloat)); return NPY_CFLOAT; } }; -template <> struct NumpyTraits > { - static int getCode() { assert(sizeof(std::complex)==sizeof(npy_cdouble)); return NPY_CDOUBLE; } +template <> struct NumpyTraits > { + static int getCode() { assert(sizeof(std::complex)==sizeof(npy_cdouble)); return NPY_CDOUBLE; } }; -template <> struct NumpyTraits > { - static int getCode() { - assert(sizeof(std::complex)==sizeof(npy_clongdouble)); - return NPY_CLONGDOUBLE; +template <> struct NumpyTraits > { + static int getCode() { + assert(sizeof(std::complex)==sizeof(npy_clongdouble)); + return NPY_CLONGDOUBLE; } }; /// \endcond -/** +/** * @internal @ingroup ndarrayPythonInternalGroup * @brief A destructor for a Python CObject that owns a shared_ptr. */ @@ -121,7 +153,7 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array::getCode(); if (actualType != requiredType) { - PyErr_SetString(PyExc_ValueError, "numpy.ndarray argument has incorrect data type"); + PyErr_SetString(PyExc_ValueError, ("numpy.ndarray argument has incorrect data type")); return false; } if (PyArray_NDIM(p.get()) != N) { @@ -134,9 +166,9 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array 0) { - int requiredStride = sizeof(Element); + std::size_t requiredStride = sizeof(Element); for (int i = 0; i < C; ++i) { - int actualStride = PyArray_STRIDE(p.get(), N-i-1); + std::size_t actualStride = PyArray_STRIDE(p.get(), N-i-1); if (actualStride != requiredStride) { PyErr_SetString( PyExc_ValueError, @@ -149,7 +181,7 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array > : public detail::PyConverterBase< Array > : public detail::PyConverterBase< Array 1) && (PyArray_STRIDE(input.get(), i) % itemsize != 0)) { PyErr_SetString( @@ -193,8 +225,8 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array shape; - Vector strides; + Vector shape; + Vector strides; std::copy(PyArray_DIMS(input.get()), PyArray_DIMS(input.get()) + N, shape.begin()); std::copy(PyArray_STRIDES(input.get()), PyArray_STRIDES(input.get()) + N , strides.begin()); for (int i = 0; i < N; ++i) strides[i] /= sizeof(Element); @@ -226,8 +258,8 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array inShape = m.getShape(); - Vector inStrides = m.getStrides(); + Vector inShape = m.getShape(); + Vector inStrides = m.getStrides(); std::copy(inShape.begin(), inShape.end(), outShape); for (int i = 0; i < N; ++i) outStrides[i] = inStrides[i] * sizeof(Element); PyPtr array( @@ -261,4 +293,4 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array + #include #include #include @@ -27,23 +29,23 @@ namespace index { * @brief Simple structure defining a noncontiguous range of indices. */ struct Slice { - int start; - int stop; - int step; + std::size_t start; + std::size_t stop; + std::size_t step; - Slice(int start_, int stop_, int step_) : start(start_), stop(stop_), step(step_) {} + Slice(std::size_t start_, std::size_t stop_, std::size_t step_) : start(start_), stop(stop_), step(step_) {} - int computeSize() const { return (step > 1) ? (stop - start + 1) / step : stop - start; } + std::size_t computeSize() const { return (step > 1) ? (stop - start + 1) / step : stop - start; } }; /** * @brief Simple structure defining a contiguous range of indices. */ struct Range { - int start; - int stop; + std::size_t start; + std::size_t stop; - Range(int start_, int stop_) : start(start_), stop(stop_) {} + Range(std::size_t start_, std::size_t stop_) : start(start_), stop(stop_) {} }; /** @@ -55,9 +57,9 @@ struct Full {}; * @brief Structure marking a single element of a dimension. */ struct Scalar { - int n; + std::size_t n; - explicit Scalar(int n_) : n(n_) {} + explicit Scalar(std::size_t n_) : n(n_) {} }; } // namespace index @@ -97,17 +99,17 @@ struct View { Full operator()() const { return Full(boost::fusion::push_back(_seq, index::Full())); } /// @brief Chain a contiguous range of the next dimension to this. - Range operator()(int start, int stop) const { + Range operator()(std::size_t start, std::size_t stop) const { return Range(boost::fusion::push_back(_seq, index::Range(start, stop))); } /// @brief Chain a noncontiguous slice of the next dimension to this. - Slice operator()(int start, int stop, int step) const { + Slice operator()(std::size_t start, std::size_t stop, std::size_t step) const { return Slice(boost::fusion::push_back(_seq, index::Slice(start, stop, step))); } /// @brief Chain a single element of the next dimension to this. - Scalar operator()(int n) const { + Scalar operator()(std::size_t n) const { return Scalar(boost::fusion::push_back(_seq, index::Scalar(n))); } }; @@ -123,21 +125,21 @@ inline View< boost::fusion::vector1 > view() { } /** @brief Start a view definition that selects a contiguous range in the first dimension. */ -inline View< boost::fusion::vector1 > view(int start, int stop) { +inline View< boost::fusion::vector1 > view(std::size_t start, std::size_t stop) { return View< boost::fusion::vector1 >( boost::fusion::make_vector(index::Range(start, stop)) ); } /** @brief Start a view definition that selects a noncontiguous slice of the first dimension. */ -inline View< boost::fusion::vector1 > view(int start, int stop, int step) { +inline View< boost::fusion::vector1 > view(std::size_t start, std::size_t stop, std::size_t step) { return View< boost::fusion::vector1 >( boost::fusion::make_vector(index::Slice(start, stop, step)) ); } /** @brief Start a view definition that selects single element from the first dimension. */ -inline View< boost::fusion::vector1 > view(int n) { +inline View< boost::fusion::vector1 > view(std::size_t n) { return View< boost::fusion::vector1 >( boost::fusion::make_vector(index::Scalar(n)) ); diff --git a/include/ndarray_fwd.h b/include/ndarray_fwd.h index d9b62069..3cc1e1ac 100644 --- a/include/ndarray_fwd.h +++ b/include/ndarray_fwd.h @@ -25,6 +25,8 @@ /// @internal \defgroup ndarrayInternalGroup Internals +#include + #include #include #include @@ -101,4 +103,4 @@ template struct Vector; } // namespace ndarray -#endif // !NDARRAY_ndarray_fwd_h_INCLUDED +#endif // !NDARRAY_ndarray_fwd_h_INCLUDED \ No newline at end of file diff --git a/tests/SConscript b/tests/SConscript index c65c70ac..2e5f5c65 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -8,6 +8,7 @@ # of the source distribution, or alternately available at: # https://github.com/ndarray/ndarray # +import os import sys def RunBinaryUnitTest(target, source, env): @@ -15,7 +16,10 @@ def RunBinaryUnitTest(target, source, env): env.Execute(Touch(target)) def BinaryUnitTest(env, source, dependencies=None): - bin = env.Program(source) + if os.name != 'nt': + bin = env.Program(target="%s.test" % source, source=source) + else: + bin = env.Program(source) run = env.Command(".%s.succeeded" % str(source), bin, RunBinaryUnitTest) if dependencies: env.Depends(run, dependencies) @@ -40,14 +44,23 @@ if testEnv.haveBoostTest: BinaryUnitTest(testEnv, "ndarray-eigen.cc") if testEnv.haveFFTW: fftwEnv = testEnv.Clone() - fftwEnv.Append(LIBS=["fftw3"]) BinaryUnitTest(fftwEnv, "ndarray-fft.cc") if pyEnv.havePython: mod = pyEnv.LoadableModule("python_test_mod", "python_test_mod.cc", SHLIBPREFIX="") + if os.name == 'nt': + # Move the module to have the correct name. + mod = env.Command(os.path.join(Dir('.').srcnode().abspath, "python_test_mod.pyd"), + mod, + Move(os.path.join(Dir('.').srcnode().abspath, "python_test_mod.pyd"), mod[0])) PythonUnitTest(pyEnv, "python_test.py", mod) if pyEnv.haveSwig and pyEnv.haveEigen: mod = pyEnv.LoadableModule("_swig_test_mod", ["swig_test_mod.i"], SHLIBPREFIX="") + if os.name == 'nt': + # Move the module to have the correct name. + mod = env.Command(os.path.join(Dir('.').srcnode().abspath, "_swig_test_mod.pyd"), + mod, + Move(os.path.join(Dir('.').srcnode().abspath, "_swig_test_mod.pyd"), mod[0])) PythonUnitTest(pyEnv, "swig_test.py", mod) if bpEnv.haveBoostPython: @@ -57,13 +70,23 @@ if bpEnv.haveBoostPython: bpEnv.Append( LINKFLAGS = ["$__RPATH"] ) # workaround for SCons bug #1644 mod = bpEnv.LoadableModule("bp_test_mod", "bp_test_mod.cc", SHLIBPREFIX="", LIBS=libs, LIBPATH=libpath, RPATH=rpath) + if os.name == 'nt': + # Move the module to have the correct name. + mod = env.Command(os.path.join(Dir('.').srcnode().abspath, "bp_test_mod.pyd"), + mod, + Move(os.path.join(Dir('.').srcnode().abspath, "bp_test_mod.pyd"), mod[0])) PythonUnitTest(bpEnv, "bp_test.py", mod) if bpEnv.haveEigen: mod = bpEnv.LoadableModule("eigen_bp_test_mod", "eigen_bp_test_mod.cc", SHLIBPREFIX="", LIBS=libs, LIBPATH=libpath, RPATH=rpath) + if os.name == 'nt': + # Move the module to have the correct name. + mod = env.Command(os.path.join(Dir('.').srcnode().abspath, "eigen_bp_test_mod.pyd"), + mod, + Move(os.path.join(Dir('.').srcnode().abspath, "eigen_bp_test_mod.pyd"), mod[0])) PythonUnitTest(bpEnv, "eigen_bp_test.py", mod) - + env.Clean("tests", Glob("*.os")) env.Clean("tests", Glob("*.pyc")) -env.Clean("tests", Glob("*.so")) +env.Clean("tests", Glob("*.so")) \ No newline at end of file diff --git a/tests/bp_test_mod.cc b/tests/bp_test_mod.cc index 1d3a2a58..0d1d0c9d 100644 --- a/tests/bp_test_mod.cc +++ b/tests/bp_test_mod.cc @@ -8,6 +8,7 @@ * of the source distribution, or alternately available at: * https://github.com/ndarray/ndarray */ +#include #include "ndarray/bp/auto.h" @@ -18,7 +19,7 @@ static boost::mt19937 engine; static boost::uniform_int<> random_int(2, 5); template -ndarray::Array makeArray(ndarray::Vector const & shape) { +ndarray::Array makeArray(ndarray::Vector const & shape) { ndarray::Array::type,N,N> a = ndarray::allocate(shape); ndarray::Array::type,1,1> flat = ndarray::flatten<1>(a); for (int n=0; n < flat.template getSize<0>(); ++n) { @@ -27,11 +28,11 @@ ndarray::Array makeArray(ndarray::Vector const & shape) { return a; } -template -ndarray::Vector makeShape() { - ndarray::Vector shape; - for (int n=0; n +ndarray::Vector makeShape() { + ndarray::Vector shape; + for (std::size_t n=0; n(random_int(engine)); } return shape; } diff --git a/tests/ndarray-fft.cc b/tests/ndarray-fft.cc index 151f6dcc..51838926 100644 --- a/tests/ndarray-fft.cc +++ b/tests/ndarray-fft.cc @@ -8,6 +8,7 @@ * of the source distribution, or alternately available at: * https://github.com/ndarray/ndarray */ +#include #include #define BOOST_TEST_DYN_LINK @@ -21,7 +22,7 @@ template static boost::test_tools::predicate_result compareRelative( - ndarray::ExpressionBase const & a, + ndarray::ExpressionBase const & a, ndarray::ExpressionBase const & b, double tolerance = 1E-4 ) { @@ -54,8 +55,8 @@ struct FourierTransformTester { typedef ndarray::FourierTransform FFT; static void testSingle( - typename FFT::Index const & shape, - typename FFT::ElementX const * xData, + typename FFT::Index const & shape, + typename FFT::ElementX const * xData, typename FFT::ElementK const * kData ) { typename FFT::ArrayX xIn = FFT::initializeX(shape); @@ -76,8 +77,8 @@ struct FourierTransformTester { } static void testMultiplex( - typename FFT::MultiplexIndex const & shape, - typename FFT::ElementX const * xData, + typename FFT::MultiplexIndex const & shape, + typename FFT::ElementX const * xData, typename FFT::ElementK const * kData ) { typename FFT::MultiplexArrayX xIn = FFT::initializeX(shape); @@ -101,11 +102,11 @@ struct FourierTransformTester { BOOST_AUTO_TEST_CASE(real_1d) { double xData1[] = { -0.28131077, -0.25505012, -0.35444799, 1.77553825, 1.655009 }; std::complex kData1[] = { - std::complex(2.53973837,0.0), + std::complex(2.53973837,0.0), std::complex(-0.99838585,3.06854867), std::complex(-0.97476025,-0.90303271) }; - FourierTransformTester::testSingle(ndarray::makeVector(5),xData1,kData1); + FourierTransformTester::testSingle(ndarray::makeVector(5),xData1,kData1); double xData2[] = { -0.42299104, 0.12242535, 0.37497334, 0.47846245, 1.19236641, -1.54989674 }; std::complex kData2[] = { std::complex(0.19533977,0.00000000), @@ -113,7 +114,7 @@ BOOST_AUTO_TEST_CASE(real_1d) { std::complex(-0.01446277,-2.15615658), std::complex(2.09335764,0.00000000), }; - FourierTransformTester::testSingle(ndarray::makeVector(6),xData2,kData2); + FourierTransformTester::testSingle(ndarray::makeVector(6),xData2,kData2); double xData3[] = { 1.23233014, 0.80816934, -0.89026449, 0.64365113, -0.95490008, -2.31806551, 0.91599268, 0.48157162, -0.3389141 , 1.3208367 , @@ -130,7 +131,7 @@ BOOST_AUTO_TEST_CASE(real_1d) { std::complex(1.88429912,-1.97237400), std::complex(-0.76453557,-0.09069146), }; - FourierTransformTester::testMultiplex(ndarray::makeVector(3,5),xData3,kData3); + FourierTransformTester::testMultiplex(ndarray::makeVector(3,5),xData3,kData3); double xData4[] = { 0.20943609, -0.70119705, -0.04658762, -0.31573777, 0.0884646 , -0.53593713, -1.43900058, -0.60146942, -0.90063027, -1.85456039, @@ -151,7 +152,7 @@ BOOST_AUTO_TEST_CASE(real_1d) { std::complex(-1.57064806,-2.97686989), std::complex(-1.70918113,0.00000000), }; - FourierTransformTester::testMultiplex(ndarray::makeVector(3,6),xData4,kData4); + FourierTransformTester::testMultiplex(ndarray::makeVector(3,6),xData4,kData4); } BOOST_AUTO_TEST_CASE(complex_1d) { @@ -169,7 +170,7 @@ BOOST_AUTO_TEST_CASE(complex_1d) { std::complex(-4.75954620,1.77512198), std::complex(0.56926906,-1.52257831), }; - FourierTransformTester,1>::testSingle(ndarray::makeVector(5),xData1,kData1); + FourierTransformTester,1>::testSingle(ndarray::makeVector(5),xData1,kData1); std::complex xData2[] = { std::complex(1.11465199,0.04081224), std::complex(-1.08053999,0.78927525), @@ -204,7 +205,7 @@ BOOST_AUTO_TEST_CASE(complex_1d) { std::complex(4.27447257,1.85030986), std::complex(-0.74625074,-1.07986528), }; - FourierTransformTester,1>::testMultiplex(ndarray::makeVector(3,5),xData2,kData2); + FourierTransformTester,1>::testMultiplex(ndarray::makeVector(3,5),xData2,kData2); } BOOST_AUTO_TEST_CASE(real_2d) { @@ -224,7 +225,7 @@ BOOST_AUTO_TEST_CASE(real_2d) { std::complex(1.39542736,-4.26784629), std::complex(-0.37466977,1.23205340), }; - FourierTransformTester::testSingle(ndarray::makeVector(3,4),xData1,kData1); + FourierTransformTester::testSingle(ndarray::makeVector(3,4),xData1,kData1); double xData2[] = { 0.61726814, 1.02478783, 1.05838231, -0.54398019, -0.22777548, -0.52546761, -0.82971628, 1.95616799, 1.9787389 , -0.5170171 , @@ -241,7 +242,7 @@ BOOST_AUTO_TEST_CASE(real_2d) { std::complex(4.10890818,-5.68718353), std::complex(2.56065709,1.51657561), }; - FourierTransformTester::testSingle(ndarray::makeVector(3,5),xData2,kData2); + FourierTransformTester::testSingle(ndarray::makeVector(3,5),xData2,kData2); double xData3[] = { -1.40706583, -0.10390223, 1.06058569, -0.31086132, 1.05681052, 0.51060026, 0.94256284, -2.12855291, -0.44127652, -1.68077709, @@ -281,7 +282,7 @@ BOOST_AUTO_TEST_CASE(real_2d) { std::complex(2.40549637,0.26293493), std::complex(3.09482501,2.74095257), }; - FourierTransformTester::testMultiplex(ndarray::makeVector(3,3,4),xData3,kData3); + FourierTransformTester::testMultiplex(ndarray::makeVector(3,3,4),xData3,kData3); double xData4[] = { -2.02786312, -0.3539932 , 0.55001132, 0.88336882, 0.43662574, 2.01541172, -0.84654528, 0.01492169, 0.25803824, -0.94068415, @@ -322,7 +323,7 @@ BOOST_AUTO_TEST_CASE(real_2d) { std::complex(-1.21120542,2.39435110), std::complex(-2.03462006,0.80292460), }; - FourierTransformTester::testMultiplex(ndarray::makeVector(3,3,5),xData4,kData4); + FourierTransformTester::testMultiplex(ndarray::makeVector(3,3,5),xData4,kData4); } BOOST_AUTO_TEST_CASE(complex_2d) { @@ -354,7 +355,7 @@ BOOST_AUTO_TEST_CASE(complex_2d) { std::complex(-4.73536776,0.93369296), std::complex(-2.82895659,-5.93210699), }; - FourierTransformTester,2>::testSingle(ndarray::makeVector(3,4),xData1,kData1); + FourierTransformTester,2>::testSingle(ndarray::makeVector(3,4),xData1,kData1); std::complex xData2[] = { std::complex(0.19529047,1.20435172), std::complex(1.45906066,-0.97965946), @@ -431,7 +432,7 @@ BOOST_AUTO_TEST_CASE(complex_2d) { std::complex(3.38827586,-3.57929124), std::complex(-1.57540539,-1.99610520), }; - FourierTransformTester,2>::testMultiplex(ndarray::makeVector(3,3,4),xData2,kData2); + FourierTransformTester,2>::testMultiplex(ndarray::makeVector(3,3,4),xData2,kData2); }; template @@ -504,19 +505,19 @@ struct FourierOpsTester { }; BOOST_AUTO_TEST_CASE(ops) { - FourierOpsTester::testShift(ndarray::makeVector(256),ndarray::makeVector(7.25),10.0); - FourierOpsTester::testShift(ndarray::makeVector(255),ndarray::makeVector(7.25),10.0); - FourierOpsTester::testShift(ndarray::makeVector(256,256),ndarray::makeVector(7.25,6.4),10.0); - FourierOpsTester::testShift(ndarray::makeVector(256,255),ndarray::makeVector(7.25,6.4),10.0); + FourierOpsTester::testShift(ndarray::makeVector(256),ndarray::makeVector(7.25),10.0); + FourierOpsTester::testShift(ndarray::makeVector(255),ndarray::makeVector(7.25),10.0); + FourierOpsTester::testShift(ndarray::makeVector(256,256),ndarray::makeVector(7.25,6.4),10.0); + FourierOpsTester::testShift(ndarray::makeVector(256,255),ndarray::makeVector(7.25,6.4),10.0); - FourierOpsTester::testDifferentiate(ndarray::makeVector(256),10.0,0); - FourierOpsTester::testDifferentiate(ndarray::makeVector(256),10.0,1); - FourierOpsTester::testDifferentiate(ndarray::makeVector(255),10.0,0); - FourierOpsTester::testDifferentiate(ndarray::makeVector(255),10.0,1); - FourierOpsTester::testDifferentiate(ndarray::makeVector(256,256),10.0,0); - FourierOpsTester::testDifferentiate(ndarray::makeVector(256,256),10.0,1); - FourierOpsTester::testDifferentiate(ndarray::makeVector(256,255),10.0,0); - FourierOpsTester::testDifferentiate(ndarray::makeVector(256,255),10.0,1); + FourierOpsTester::testDifferentiate(ndarray::makeVector(256),10.0,0); + FourierOpsTester::testDifferentiate(ndarray::makeVector(256),10.0,1); + FourierOpsTester::testDifferentiate(ndarray::makeVector(255),10.0,0); + FourierOpsTester::testDifferentiate(ndarray::makeVector(255),10.0,1); + FourierOpsTester::testDifferentiate(ndarray::makeVector(256,256),10.0,0); + FourierOpsTester::testDifferentiate(ndarray::makeVector(256,256),10.0,1); + FourierOpsTester::testDifferentiate(ndarray::makeVector(256,255),10.0,0); + FourierOpsTester::testDifferentiate(ndarray::makeVector(256,255),10.0,1); } #else diff --git a/tests/ndarray.cc b/tests/ndarray.cc index d9b477f8..8301f743 100644 --- a/tests/ndarray.cc +++ b/tests/ndarray.cc @@ -10,6 +10,8 @@ */ #include "ndarray.h" +#include + #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE ndarray #include "boost/test/unit_test.hpp" @@ -48,8 +50,8 @@ BOOST_AUTO_TEST_CASE(vectors) { BOOST_AUTO_TEST_CASE(cores) { typedef ndarray::detail::Core<3> Core; - ndarray::Vector shape = ndarray::makeVector(4,3,2); - ndarray::Vector strides = ndarray::makeVector(6,2,1); + ndarray::Vector shape = ndarray::makeVector(4,3,2); + ndarray::Vector strides = ndarray::makeVector(6,2,1); Core::Ptr core = Core::create(shape, strides); BOOST_CHECK_EQUAL(core->getRC(),1); Core::Ptr copy = core; @@ -59,7 +61,7 @@ BOOST_AUTO_TEST_CASE(cores) { } BOOST_AUTO_TEST_CASE(allocation) { - ndarray::Vector shape = ndarray::makeVector(5,6,7); + ndarray::Vector shape = ndarray::makeVector(5,6,7); ndarray::Array a = ndarray::allocate(shape); BOOST_CHECK_EQUAL(a.getShape(), shape); @@ -71,7 +73,7 @@ BOOST_AUTO_TEST_CASE(allocation) { BOOST_CHECK_EQUAL(b.getStride<0>(), 6*7); BOOST_CHECK_EQUAL(b.getStride<1>(), 7); BOOST_CHECK_EQUAL(b.getStride<2>(), 1); - BOOST_CHECK_EQUAL(b.getStrides(), ndarray::makeVector(6*7 ,7, 1)); + BOOST_CHECK_EQUAL(b.getStrides(), ndarray::makeVector(6*7 ,7, 1)); ndarray::Array c = ndarray::allocate(5,6,7); BOOST_CHECK_EQUAL(c.getShape(), shape); @@ -81,14 +83,14 @@ BOOST_AUTO_TEST_CASE(allocation) { BOOST_CHECK_EQUAL(c.getStride<0>(), 1); BOOST_CHECK_EQUAL(c.getStride<1>(), 5); BOOST_CHECK_EQUAL(c.getStride<2>(), 5*6); - BOOST_CHECK_EQUAL(c.getStrides(), ndarray::makeVector(1, 5, 5*6)); - + BOOST_CHECK_EQUAL(c.getStrides(), ndarray::makeVector(1, 5, 5*6)); + } BOOST_AUTO_TEST_CASE(external) { double data[3*4*2] = {0}; - ndarray::Vector shape = ndarray::makeVector(3,4,2); - ndarray::Vector strides = ndarray::makeVector(8,2,1); + ndarray::Vector shape = ndarray::makeVector(3,4,2); + ndarray::Vector strides = ndarray::makeVector(8,2,1); ndarray::Array a = ndarray::external(data,shape,strides); BOOST_CHECK_EQUAL(a.getData(), data); BOOST_CHECK_EQUAL(a.getShape(), shape); @@ -97,16 +99,16 @@ BOOST_AUTO_TEST_CASE(external) { BOOST_AUTO_TEST_CASE(conversion) { double data[3*4*2] = {0}; - ndarray::Vector shape = ndarray::makeVector(3,4,2); - ndarray::Vector strides = ndarray::makeVector(8,2,1); + ndarray::Vector shape = ndarray::makeVector(3,4,2); + ndarray::Vector strides = ndarray::makeVector(8,2,1); ndarray::Array a = ndarray::external(data,shape,strides); ndarray::Array b = a; } BOOST_AUTO_TEST_CASE(shallow) { double data[3*4*2] = {0}; - ndarray::Vector shape = ndarray::makeVector(3,4,2); - ndarray::Vector strides = ndarray::makeVector(8,2,1); + ndarray::Vector shape = ndarray::makeVector(3,4,2); + ndarray::Vector strides = ndarray::makeVector(8,2,1); ndarray::Array a = ndarray::external(data,shape,strides); ndarray::Array b = ndarray::external(data,shape,strides); BOOST_CHECK(a == b); @@ -128,8 +130,8 @@ BOOST_AUTO_TEST_CASE(shallow) { BOOST_AUTO_TEST_CASE(casts) { double data[3*4*2] = {0}; - ndarray::Vector shape = ndarray::makeVector(3,4,2); - ndarray::Vector strides = ndarray::makeVector(8,2,1); + ndarray::Vector shape = ndarray::makeVector(3,4,2); + ndarray::Vector strides = ndarray::makeVector(8,2,1); ndarray::Array a = ndarray::external(data,shape,strides); ndarray::Array b = ndarray::static_dimension_cast<2>(a); BOOST_CHECK(a == b); @@ -144,8 +146,8 @@ BOOST_AUTO_TEST_CASE(casts) { BOOST_AUTO_TEST_CASE(complex) { std::complex data[3*4*2] = { std::complex(0.0,0.0) }; - ndarray::Vector shape = ndarray::makeVector(3,4,2); - ndarray::Vector strides = ndarray::makeVector(8,2,1); + ndarray::Vector shape = ndarray::makeVector(3,4,2); + ndarray::Vector strides = ndarray::makeVector(8,2,1); ndarray::Array,3,3> a = ndarray::external(data,shape,strides); ndarray::Array re(getReal(a)); ndarray::Array im(getImag(a)); @@ -155,40 +157,40 @@ BOOST_AUTO_TEST_CASE(complex) { } BOOST_AUTO_TEST_CASE(indexing) { - double data[3*4*2] = { + double data[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - ndarray::Vector a_shape = ndarray::makeVector(4,3,2); - ndarray::Vector a_strides = ndarray::makeVector(6,2,1); + ndarray::Vector a_shape = ndarray::makeVector(4,3,2); + ndarray::Vector a_strides = ndarray::makeVector(6,2,1); ndarray::Array a = ndarray::external(data, a_shape, a_strides); BOOST_CHECK(a.front().shallow() == a[0].shallow()); BOOST_CHECK(a.back().shallow() == a[a_shape[0]-1].shallow()); - int n = 0; - for (int i=0; i b_shape = ndarray::makeVector(8,3); - ndarray::Vector b_strides = ndarray::makeVector(1,8); + ndarray::Vector b_shape = ndarray::makeVector(8,3); + ndarray::Vector b_strides = ndarray::makeVector(1,8); ndarray::Array b = ndarray::external(data, b_shape, b_strides); - for (int i=0; i c_shape = ndarray::makeVector(4,3); - ndarray::Vector c_strides = ndarray::makeVector(1,8); + ndarray::Vector c_shape = ndarray::makeVector(4,3); + ndarray::Vector c_strides = ndarray::makeVector(1,8); ndarray::Array c = ndarray::external(data, c_shape, c_strides); - for (int i=0; i a_shape = ndarray::makeVector(4,3,2); - ndarray::Vector a_strides = ndarray::makeVector(6,2,1); + ndarray::Vector a_shape = ndarray::makeVector(4,3,2); + ndarray::Vector a_strides = ndarray::makeVector(6,2,1); ndarray::Array a = ndarray::external(data, a_shape, a_strides); ndarray::Array::Iterator ai_iter = a.begin(); ndarray::Array::Iterator const ai_end = a.end(); @@ -217,8 +219,8 @@ BOOST_AUTO_TEST_CASE(iterators) { } } } - ndarray::Vector b_shape = ndarray::makeVector(4,3); - ndarray::Vector b_strides = ndarray::makeVector(1,8); + ndarray::Vector b_shape = ndarray::makeVector(4,3); + ndarray::Vector b_strides = ndarray::makeVector(1,8); ndarray::Array b = ndarray::external(data, b_shape, b_strides); ndarray::Array::Iterator bi_iter = b.begin(); ndarray::Array::Iterator const bi_end = b.end(); @@ -233,38 +235,38 @@ BOOST_AUTO_TEST_CASE(iterators) { } BOOST_AUTO_TEST_CASE(views) { - ndarray::Vector shape = ndarray::makeVector(4,3,2); + ndarray::Vector shape = ndarray::makeVector(4,3,2); ndarray::Array a = ndarray::allocate(shape); BOOST_CHECK(a == a[ndarray::view()()].shallow()); BOOST_CHECK(a == a[ndarray::view()].shallow()); - BOOST_CHECK(a[1].shallow() == a[ndarray::view(1)].shallow()); - BOOST_CHECK(a[1][2].shallow() == a[ndarray::view(1)(2)].shallow()); + BOOST_CHECK(a[1].shallow() == a[ndarray::view((std::size_t)1)].shallow()); + BOOST_CHECK(a[1][2].shallow() == a[ndarray::view((std::size_t)1)((std::size_t)2)].shallow()); BOOST_CHECK(a != a[ndarray::view(0,3)].shallow()); ndarray::Array b = a[ndarray::view()(1,3)(0)]; - BOOST_CHECK(b.getShape() == ndarray::makeVector(4,2)); - BOOST_CHECK(b.getStrides() == ndarray::makeVector(6,2)); + BOOST_CHECK(b.getShape() == ndarray::makeVector(4,2)); + BOOST_CHECK(b.getStrides() == ndarray::makeVector(6,2)); BOOST_CHECK(b.getData() == a.getData() + 2); ndarray::Array c = b[ndarray::view(0,4,2)()]; - BOOST_CHECK(c.getShape() == ndarray::makeVector(2,2)); - BOOST_CHECK(c.getStrides() == ndarray::makeVector(12,2)); + BOOST_CHECK(c.getShape() == ndarray::makeVector(2,2)); + BOOST_CHECK(c.getStrides() == ndarray::makeVector(12,2)); BOOST_CHECK(c.getData() == b.getData()); } #ifndef GCC_45 BOOST_AUTO_TEST_CASE(predicates) { - double data1[3*4*2] = { + double data1[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - double data2[3*4*2] = { + double data2[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - ndarray::Vector shape = ndarray::makeVector(4,3,2); - ndarray::Vector strides = ndarray::makeVector(6,2,1); + ndarray::Vector shape = ndarray::makeVector(4,3,2); + ndarray::Vector strides = ndarray::makeVector(6,2,1); ndarray::Array a = ndarray::external(data1, shape, strides); ndarray::Array b = ndarray::allocate(shape); ndarray::Array c = ndarray::allocate(shape); @@ -299,15 +301,15 @@ BOOST_AUTO_TEST_CASE(predicates) { } BOOST_AUTO_TEST_CASE(allclose) { - float data[3*4*2] = { + float data[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - ndarray::Vector shape = ndarray::makeVector(4,3,2); - ndarray::Vector strides = ndarray::makeVector(6,2,1); + ndarray::Vector shape = ndarray::makeVector(4,3,2); + ndarray::Vector strides = ndarray::makeVector(6,2,1); ndarray::Array a = ndarray::external(data,shape,strides); - ndarray::Array b = ndarray::allocate(ndarray::concatenate(shape, 3)); + ndarray::Array b = ndarray::allocate(ndarray::concatenate(shape, (std::size_t)3)); ndarray::Array c = ndarray::allocate(shape); c.deep() = a + 1.2; b.deep() = a + 1.2; @@ -318,13 +320,13 @@ BOOST_AUTO_TEST_CASE(allclose) { } BOOST_AUTO_TEST_CASE(binary_ops) { - float data[3*4*2] = { + float data[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - ndarray::Vector shape = ndarray::makeVector(4,3,2); - ndarray::Vector strides = ndarray::makeVector(6,2,1); + ndarray::Vector shape = ndarray::makeVector(4,3,2); + ndarray::Vector strides = ndarray::makeVector(6,2,1); ndarray::Array a = ndarray::external(data,shape,strides); ndarray::Array b = ndarray::allocate(shape); ndarray::Array c = ndarray::allocate(shape); @@ -344,21 +346,21 @@ BOOST_AUTO_TEST_CASE(binary_ops) { } BOOST_AUTO_TEST_CASE(broadcasting) { - double data3[3*4*2] = { + double data3[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - double data2[3*4] = { + double data2[3*4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, }; - double data32[3*4*2] = { + double data32[3*4*2] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, }; - ndarray::Vector shape3 = ndarray::makeVector(3,4,2); - ndarray::Vector strides3 = ndarray::makeVector(8,2,1); - ndarray::Vector shape2 = ndarray::makeVector(3,4); - ndarray::Vector strides2 = ndarray::makeVector(4,1); + ndarray::Vector shape3 = ndarray::makeVector(3,4,2); + ndarray::Vector strides3 = ndarray::makeVector(8,2,1); + ndarray::Vector shape2 = ndarray::makeVector(3,4); + ndarray::Vector strides2 = ndarray::makeVector(4,1); ndarray::Array a3 = ndarray::external(data3,shape3,strides3); ndarray::Array a32 = ndarray::external(data32,shape3,strides3); ndarray::Array a2 = ndarray::external(data2,shape2,strides2); @@ -380,13 +382,13 @@ BOOST_AUTO_TEST_CASE(broadcasting) { #endif BOOST_AUTO_TEST_CASE(assignment) { - double data[3*4*2] = { + double data[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - ndarray::Vector shape = ndarray::makeVector(3,4,2); - ndarray::Vector strides = ndarray::makeVector(8,2,1); + ndarray::Vector shape = ndarray::makeVector(3,4,2); + ndarray::Vector strides = ndarray::makeVector(8,2,1); ndarray::Array a = ndarray::external(data,shape,strides); ndarray::Array b = ndarray::allocate(shape); b.deep() = a; @@ -438,11 +440,11 @@ BOOST_AUTO_TEST_CASE(transpose) { 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - ndarray::Vector shape = ndarray::makeVector(3,4,2); - ndarray::Vector strides = ndarray::makeVector(8,2,1); + ndarray::Vector shape = ndarray::makeVector(3,4,2); + ndarray::Vector strides = ndarray::makeVector(8,2,1); ndarray::Array a = ndarray::external(data,shape,strides); ndarray::Array b = a.transpose(); - ndarray::Array c = a.transpose(ndarray::makeVector(1,0,2)); + ndarray::Array c = a.transpose(ndarray::makeVector(1,0,2)); for (int i=0; i a1 = a[ndarray::view(0)()()]; - ndarray::Array b1 = b[ndarray::view()()(0)]; + ndarray::Array a1 = a[ndarray::view((std::size_t)0)()()]; + ndarray::Array b1 = b[ndarray::view()()((std::size_t)0)]; BOOST_CHECK(b1.transpose().shallow() == a1.shallow()); BOOST_CHECK(a1.transpose().shallow() == b1.shallow()); } @@ -496,22 +498,26 @@ BOOST_AUTO_TEST_CASE(transpose) { } BOOST_AUTO_TEST_CASE(flatten) { - double data[3*4*2] = { + double data[3*4*2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, }; - ndarray::Vector a_shape = ndarray::makeVector(4,3,2); - ndarray::Vector a_strides = ndarray::makeVector(6,2,1); + ndarray::Vector a_shape = ndarray::makeVector(4,3,2); + ndarray::Vector a_strides = ndarray::makeVector(6,2,1); ndarray::Array a = ndarray::external(data,a_shape,a_strides); ndarray::Array b = ndarray::flatten<2>(a); ndarray::Array b_check = ndarray::external( - data, ndarray::makeVector(4,6), ndarray::makeVector(6,1) + data, + ndarray::makeVector(4,6), + ndarray::makeVector(6,1) ); BOOST_CHECK(b.shallow() == b_check.shallow()); ndarray::Array c = ndarray::flatten<1>(a); ndarray::Array c_check = ndarray::external( - data, ndarray::makeVector(24), ndarray::makeVector(1) + data, + ndarray::makeVector(24), + ndarray::makeVector(1) ); } @@ -522,7 +528,7 @@ BOOST_AUTO_TEST_CASE(unique) { BOOST_CHECK(!a.isUnique()); BOOST_CHECK(!b.isUnique()); a = ndarray::Array(); - BOOST_CHECK(b.isUnique()); + BOOST_CHECK(b.isUnique()); ndarray::Array c = b[ndarray::view(1,4)(1,3)]; BOOST_CHECK(!c.isUnique()); BOOST_CHECK(!b.isUnique()); @@ -562,7 +568,7 @@ BOOST_AUTO_TEST_CASE(zeroSize) { BOOST_AUTO_TEST_CASE(manager) { ndarray::Array a = ndarray::allocate(5); - ndarray::Array b + ndarray::Array b = ndarray::external(a.getData(), a.getShape(), a.getStrides(), a.getManager()); BOOST_CHECK_EQUAL(a.getManager(), b.getManager()); // no extra indirection in makeManager } diff --git a/tests/python_test.py b/tests/python_test.py index 8a290d78..1243f8c4 100755 --- a/tests/python_test.py +++ b/tests/python_test.py @@ -20,11 +20,19 @@ def testIntArrayConversion(self): self.assert_(a1.flags["WRITEABLE"]) self.assert_(a2.flags["WRITEABLE"]) + ua1 = numpy.zeros((5,3,4),dtype=numpy.uint32) + self.assert_(ua1.flags["WRITEABLE"]) + b1 = python_test_mod.passIntArray33(a1) self.assert_(b1.flags["WRITEABLE"]) self.assertEqual(a1.shape,b1.shape) self.assertEqual(a1.strides,b1.strides) + ub1 = python_test_mod.passuIntArray33(ua1) + self.assert_(ub1.flags["WRITEABLE"]) + self.assertEqual(a1.shape,ub1.shape) + self.assertEqual(a1.strides,ub1.strides) + c1 = python_test_mod.passIntArray30(a1) self.assert_(c1.flags["WRITEABLE"]) self.assertEqual(a1.shape,c1.shape) @@ -46,7 +54,7 @@ def testIntArrayConversion(self): self.assertRaises(TypeError, python_test_mod.passIntArray30, ((1,1,1),(2,2,2),(3,3,3))) # test to be sure an array of the wrong type does not work - self.assertRaises(ValueError, python_test_mod.passIntArray30, + self.assertRaises(ValueError, python_test_mod.passIntArray30, numpy.zeros((4,3,4),dtype=numpy.float)) def testVectorConversion(self): @@ -84,7 +92,7 @@ def testArrayConversion(self): self.assertEqual(a2.strides,c2.strides) # test to be sure a tuple of tuples does not work - self.assertRaises(TypeError, python_test_mod.passFloatArray30, + self.assertRaises(TypeError, python_test_mod.passFloatArray30, ((1.0,1.0,1.0),(2.0,2.0,2.0),(3.0,3.0,3.0))) # test to be sure an array of the wrong type does not work @@ -101,7 +109,7 @@ def testArrayConversion(self): def testFloatArrayCreation(self): a = python_test_mod.makeFloatArray3((3,4,5)) - + def testIntArrayCreation(self): a = python_test_mod.makeIntArray3((3,4,5)) diff --git a/tests/python_test_mod.cc b/tests/python_test_mod.cc index 3b4f6cfc..f5366800 100644 --- a/tests/python_test_mod.cc +++ b/tests/python_test_mod.cc @@ -8,10 +8,13 @@ * of the source distribution, or alternately available at: * https://github.com/ndarray/ndarray */ +#include #include "Python.h" #include "numpy/arrayobject.h" #include "ndarray/swig.h" +#ifndef _MSC_VER #pragma GCC diagnostic ignored "-Wuninitialized" +#endif template static PyObject * passVector(PyObject * self, PyObject * args) { @@ -31,8 +34,8 @@ static PyObject * passArray(PyObject * self, PyObject * args) { template static PyObject * makeArray(PyObject * self, PyObject * args) { - ndarray::Vector shape; - if (!PyArg_ParseTuple(args,"O&",ndarray::PyConverter< ndarray::Vector >::fromPython,&shape)) + ndarray::Vector shape; + if (!PyArg_ParseTuple(args,"O&",ndarray::PyConverter< ndarray::Vector >::fromPython,&shape)) return NULL; ndarray::Array array = ndarray::allocate(shape); array.deep() = static_cast(0); @@ -47,6 +50,7 @@ static PyMethodDef methods[] = { {"makeFloatArray3",&makeArray,METH_VARARGS,NULL}, {"passIntVector3",&passVector,METH_VARARGS,NULL}, {"passIntArray33",&passArray,METH_VARARGS,NULL}, + {"passuIntArray33",&passArray,METH_VARARGS,NULL}, {"passConstIntArray33",&passArray,METH_VARARGS,NULL}, {"passIntArray30",&passArray,METH_VARARGS,NULL}, {"makeIntArray3",&makeArray,METH_VARARGS,NULL}, diff --git a/tests/swig_test_mod.i b/tests/swig_test_mod.i index 1c9c8e11..b93853d1 100644 --- a/tests/swig_test_mod.i +++ b/tests/swig_test_mod.i @@ -11,10 +11,13 @@ %module swig_test_mod %{ #define PY_ARRAY_UNIQUE_SYMBOL LSST_SWIG_TEST_NUMPY_ARRAY_API +#include #include "numpy/arrayobject.h" #include "ndarray/swig.h" #include "ndarray/swig/eigen.h" +#ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wuninitialized" +#endif %} %init %{ import_array(); @@ -51,7 +54,7 @@ Eigen::Matrix2d returnMatrix2d() { } ndarray::Array returnArray1() { - ndarray::Array r(ndarray::allocate(ndarray::makeVector(6))); + ndarray::Array r(ndarray::allocate(ndarray::makeVector(6))); for (int n = 0; n < r.getSize<0>(); ++n) { r[n] = n; } @@ -63,9 +66,9 @@ ndarray::Array returnConstArray1() { } ndarray::Array returnArray3() { - ndarray::Array r(ndarray::allocate(ndarray::makeVector(4,3,2))); + ndarray::Array r(ndarray::allocate(ndarray::makeVector(4,3,2))); ndarray::Array f = ndarray::flatten<1>(r); - for (int n = 0; n < f.getSize<0>(); ++n) { + for (std::size_t n = 0; n < f.getSize<0>(); ++n) { f[n] = n; } return r; @@ -101,8 +104,8 @@ bool acceptArray3(ndarray::Array const & a1) { #ifndef GCC_45 return ndarray::all(ndarray::equal(a1, a2)); #else - for (int i = 0; i < a1.getSize<0>(); ++i) { - for (int j = 0; j < a1.getSize<1>(); ++j) { + for (std::size_t i = 0; i < a1.getSize<0>(); ++i) { + for (std::size_t j = 0; j < a1.getSize<1>(); ++j) { if (!std::equal(a1[i][j].begin(), a1[i][j].end(), a2[i][j].begin())) return false; } }