File indexing completed on 2025-02-22 10:26:15
0001
0002
0003
0004
0005
0006
0007 #ifndef boost_python_numpy_ufunc_hpp_
0008 #define boost_python_numpy_ufunc_hpp_
0009
0010
0011
0012
0013
0014 #include <boost/python.hpp>
0015 #include <boost/python/numpy/numpy_object_mgr_traits.hpp>
0016 #include <boost/python/numpy/dtype.hpp>
0017 #include <boost/python/numpy/ndarray.hpp>
0018 #include <boost/python/numpy/config.hpp>
0019
0020 namespace boost { namespace python { namespace numpy {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class BOOST_NUMPY_DECL multi_iter : public object
0039 {
0040 public:
0041
0042 BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(multi_iter, object);
0043
0044
0045 void next();
0046
0047
0048 bool not_done() const;
0049
0050
0051 char * get_data(int n) const;
0052
0053
0054 int get_nd() const;
0055
0056
0057 Py_intptr_t const * get_shape() const;
0058
0059
0060 Py_intptr_t shape(int n) const;
0061
0062 };
0063
0064
0065 BOOST_NUMPY_DECL multi_iter make_multi_iter(object const & a1);
0066
0067
0068 BOOST_NUMPY_DECL multi_iter make_multi_iter(object const & a1, object const & a2);
0069
0070
0071 BOOST_NUMPY_DECL multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template <typename TUnaryFunctor,
0095 typename TArgument=typename TUnaryFunctor::argument_type,
0096 typename TResult=typename TUnaryFunctor::result_type>
0097 struct unary_ufunc
0098 {
0099
0100
0101
0102
0103
0104 static object call(TUnaryFunctor & self, object const & input, object const & output)
0105 {
0106 dtype in_dtype = dtype::get_builtin<TArgument>();
0107 dtype out_dtype = dtype::get_builtin<TResult>();
0108 ndarray in_array = from_object(input, in_dtype, ndarray::ALIGNED);
0109 ndarray out_array = ! output.is_none() ?
0110 from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
0111 : zeros(in_array.get_nd(), in_array.get_shape(), out_dtype);
0112 multi_iter iter = make_multi_iter(in_array, out_array);
0113 while (iter.not_done())
0114 {
0115 TArgument * argument = reinterpret_cast<TArgument*>(iter.get_data(0));
0116 TResult * result = reinterpret_cast<TResult*>(iter.get_data(1));
0117 *result = self(*argument);
0118 iter.next();
0119 }
0120 return out_array.scalarize();
0121 }
0122
0123
0124
0125
0126
0127
0128
0129 static object make()
0130 {
0131 return make_function(call, default_call_policies(), (arg("input"), arg("output")=object()));
0132 }
0133 };
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 template <typename TBinaryFunctor,
0158 typename TArgument1=typename TBinaryFunctor::first_argument_type,
0159 typename TArgument2=typename TBinaryFunctor::second_argument_type,
0160 typename TResult=typename TBinaryFunctor::result_type>
0161 struct binary_ufunc
0162 {
0163
0164 static object
0165 call(TBinaryFunctor & self, object const & input1, object const & input2,
0166 object const & output)
0167 {
0168 dtype in1_dtype = dtype::get_builtin<TArgument1>();
0169 dtype in2_dtype = dtype::get_builtin<TArgument2>();
0170 dtype out_dtype = dtype::get_builtin<TResult>();
0171 ndarray in1_array = from_object(input1, in1_dtype, ndarray::ALIGNED);
0172 ndarray in2_array = from_object(input2, in2_dtype, ndarray::ALIGNED);
0173 multi_iter iter = make_multi_iter(in1_array, in2_array);
0174 ndarray out_array = !output.is_none()
0175 ? from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
0176 : zeros(iter.get_nd(), iter.get_shape(), out_dtype);
0177 iter = make_multi_iter(in1_array, in2_array, out_array);
0178 while (iter.not_done())
0179 {
0180 TArgument1 * argument1 = reinterpret_cast<TArgument1*>(iter.get_data(0));
0181 TArgument2 * argument2 = reinterpret_cast<TArgument2*>(iter.get_data(1));
0182 TResult * result = reinterpret_cast<TResult*>(iter.get_data(2));
0183 *result = self(*argument1, *argument2);
0184 iter.next();
0185 }
0186 return out_array.scalarize();
0187 }
0188
0189 static object make()
0190 {
0191 return make_function(call, default_call_policies(),
0192 (arg("input1"), arg("input2"), arg("output")=object()));
0193 }
0194
0195 };
0196
0197 }
0198
0199 namespace converter
0200 {
0201
0202 NUMPY_OBJECT_MANAGER_TRAITS(numpy::multi_iter);
0203
0204 }}}
0205
0206 #endif