Go to the documentation of this file.00001
00002
00003
00004
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 }
00201
00202 namespace python
00203 {
00204 namespace converter
00205 {
00206
00207 NUMPY_OBJECT_MANAGER_TRAITS(numpy::multi_iter);
00208
00209 }
00210 }
00211 }
00212
00213 #endif // !BOOST_NUMPY_UFUNC_HPP_INCLUDED