ufunc.hpp
Go to the documentation of this file.
00001 // Copyright Jim Bosch 2010-2012.
00002 // Distributed under the Boost Software License, Version 1.0.
00003 //    (See accompanying file LICENSE_1_0.txt or copy at
00004 //          http://www.boost.org/LICENSE_1_0.txt)
00005 #ifndef BOOST_NUMPY_UFUNC_HPP_INCLUDED
00006 #define BOOST_NUMPY_UFUNC_HPP_INCLUDED
00007 
00013 #include <boost/python.hpp>
00014 #include <boost/numpy/numpy_object_mgr_traits.hpp>
00015 #include <boost/numpy/dtype.hpp>
00016 #include <boost/numpy/ndarray.hpp>
00017 
00018 namespace boost 
00019 {
00020 namespace numpy 
00021 {
00022 
00039 class multi_iter : public python::object 
00040 {
00041 public:
00042 
00043   BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(multi_iter, python::object);
00044 
00046   void next();
00047 
00049   bool not_done() const;
00050 
00052   char * get_data(int n) const;
00053 
00055   int const get_nd() const;
00056     
00058   Py_intptr_t const * get_shape() const;
00059 
00061   Py_intptr_t const shape(int n) const;
00062     
00063 };
00064 
00066 multi_iter make_multi_iter(python::object const & a1);
00067 
00069 multi_iter make_multi_iter(python::object const & a1, python::object const & a2);
00070 
00072 multi_iter make_multi_iter(python::object const & a1, python::object const & a2, python::object const & a3);
00073 
00095 template <typename TUnaryFunctor, 
00096           typename TArgument=typename TUnaryFunctor::argument_type,
00097           typename TResult=typename TUnaryFunctor::result_type>
00098 struct unary_ufunc 
00099 {
00100 
00105   static python::object call(TUnaryFunctor & self, python::object const & input, python::object const & output) 
00106   {
00107     dtype in_dtype = dtype::get_builtin<TArgument>();
00108     dtype out_dtype = dtype::get_builtin<TResult>();
00109     ndarray in_array = from_object(input, in_dtype, ndarray::ALIGNED);
00110     ndarray out_array = (output != python::object()) ? 
00111       from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
00112       : zeros(in_array.get_nd(), in_array.get_shape(), out_dtype);
00113     multi_iter iter = make_multi_iter(in_array, out_array);
00114     while (iter.not_done()) 
00115     {
00116       TArgument * argument = reinterpret_cast<TArgument*>(iter.get_data(0));
00117       TResult * result = reinterpret_cast<TResult*>(iter.get_data(1));
00118       *result = self(*argument);
00119       iter.next();
00120     } 
00121     return out_array.scalarize();
00122   }
00123 
00130   static python::object make() 
00131   {
00132     namespace p = python;
00133     return p::make_function(call, p::default_call_policies(), (p::arg("input"), p::arg("output")=p::object())); 
00134   }
00135 };
00136 
00159 template <typename TBinaryFunctor, 
00160           typename TArgument1=typename TBinaryFunctor::first_argument_type,
00161           typename TArgument2=typename TBinaryFunctor::second_argument_type,
00162           typename TResult=typename TBinaryFunctor::result_type>
00163 struct binary_ufunc 
00164 {
00165 
00166   static python::object 
00167   call(TBinaryFunctor & self, python::object const & input1, python::object const & input2, 
00168        python::object const & output) 
00169   {
00170     dtype in1_dtype = dtype::get_builtin<TArgument1>();
00171     dtype in2_dtype = dtype::get_builtin<TArgument2>();
00172     dtype out_dtype = dtype::get_builtin<TResult>();
00173     ndarray in1_array = from_object(input1, in1_dtype, ndarray::ALIGNED);
00174     ndarray in2_array = from_object(input2, in2_dtype, ndarray::ALIGNED);
00175     multi_iter iter = make_multi_iter(in1_array, in2_array);
00176     ndarray out_array = (output != python::object())
00177       ? from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
00178       : zeros(iter.get_nd(), iter.get_shape(), out_dtype);
00179     iter = make_multi_iter(in1_array, in2_array, out_array);
00180     while (iter.not_done()) 
00181     {
00182       TArgument1 * argument1 = reinterpret_cast<TArgument1*>(iter.get_data(0));
00183       TArgument2 * argument2 = reinterpret_cast<TArgument2*>(iter.get_data(1));
00184       TResult * result = reinterpret_cast<TResult*>(iter.get_data(2));
00185       *result = self(*argument1, *argument2);
00186       iter.next();
00187     } 
00188     return out_array.scalarize();
00189   }
00190 
00191   static python::object make() 
00192   {
00193     namespace p = python;
00194     return p::make_function(call, p::default_call_policies(), 
00195                             (p::arg("input1"), p::arg("input2"), p::arg("output")=p::object())); 
00196   }
00197 
00198 };
00199 
00200 } // namespace boost::numpy
00201 
00202 namespace python
00203 {
00204 namespace converter 
00205 {
00206 
00207 NUMPY_OBJECT_MANAGER_TRAITS(numpy::multi_iter);
00208 
00209 } // namespace boost::python::converter
00210 } // namespace boost::python
00211 } // namespace boost
00212 
00213 #endif // !BOOST_NUMPY_UFUNC_HPP_INCLUDED


boost_numpy
Author(s): Jim Bosch, Ankit Daftery
autogenerated on Fri Aug 28 2015 10:10:40