#ifndef SCITBX_ARRAY_FAMILY_BOOST_PYTHON_FLEX_WRAPPER_H #define SCITBX_ARRAY_FAMILY_BOOST_PYTHON_FLEX_WRAPPER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace scitbx { namespace af { namespace boost_python { using scitbx::positive_getitem_index; template array_t _getitem_tuple_helper(PyObject* obj_ptr) { boost::python::handle<> obj_iter(PyObject_GetIter(obj_ptr)); array_t result; std::size_t i=0; for(;;i++) { boost::python::handle<> py_elem_hdl( boost::python::allow_null(PyIter_Next(obj_iter.get()))); if (PyErr_Occurred()) boost::python::throw_error_already_set(); if (!py_elem_hdl.get()) break; // end of iteration boost::python::object py_elem_obj(py_elem_hdl); boost::python::extract elem_proxy(py_elem_obj); bool success = elem_proxy.check(); if (success) { result.push_back(elem_proxy()); } else if (i == 0) { break; } else { PyErr_SetString(PyExc_TypeError, "All items must be of same type."); boost::python::throw_error_already_set(); } } return result; } template struct flex_default_element { static ElementType get() { return ElementType(); } }; template > struct flex_wrapper : versa > { typedef ElementType e_t; typedef versa > f_t; typedef typename f_t::base_array_type base_array_type; // Tell the compiler how to convert a base class object to // this wrapper object. flex_wrapper(PyObject*, f_t const& v) : f_t(v) {} flex_wrapper(PyObject*) : f_t(flex_grid<>(0), flex_default_element::get()) {} flex_wrapper(PyObject*, flex_grid<> const& fg) : f_t(fg, flex_default_element::get()) {} flex_wrapper(PyObject*, flex_grid<> const& fg, ElementType const& x) : f_t(fg, x) {} flex_wrapper(PyObject*, std::size_t n) : f_t(flex_grid<>(n), flex_default_element::get()) {} flex_wrapper(PyObject*, std::size_t n, ElementType const& x) : f_t(flex_grid<>(n), x) {} flex_wrapper(PyObject*, shared_plain const& a) : f_t(a, flex_grid<>(a.size())) {} static std::size_t element_size() { return sizeof(ElementType); } static flex_grid<> accessor(f_t const& a) { return a.accessor(); } static std::size_t nd(f_t const& a) { return a.accessor().nd(); } static bool is_0_based(f_t const& a) { return a.accessor().is_0_based(); } static flex_grid_default_index_type origin(f_t const& a) { return a.accessor().origin(); } static flex_grid_default_index_type all(f_t const& a) { return a.accessor().all(); } static flex_grid_default_index_type last_0(f_t const& a) { return a.accessor().last(); } static flex_grid_default_index_type last_1(f_t const& a, bool open_range) { return a.accessor().last(open_range); } static bool is_padded(f_t const& a) { return a.accessor().is_padded(); } static flex_grid_default_index_type focus_0(f_t const& a) { return a.accessor().focus(); } static flex_grid_default_index_type focus_1(f_t const& a, bool open_range) { return a.accessor().focus(open_range); } static std::size_t focus_size_1d(f_t const& a) { return a.accessor().focus_size_1d(); } static bool is_trivial_1d(f_t const& a) { return a.accessor().is_trivial_1d(); } static f_t shift_origin(f_t const& a) { return f_t(a, a.accessor().shift_origin()); } static std::size_t id(f_t const& a) { return a.id(); } static std::size_t size(f_t const& a) { return a.size(); } static std::size_t capacity(f_t const& a) { return a.capacity(); } static e_t& getitem_1d(f_t& a, long i) { if (!a.check_shared_size()) raise_shared_size_mismatch(); std::size_t j = positive_getitem_index(i, a.size()); return a[j]; } static f_t getitem_1d_slice(f_t const& a, boost::python::slice const& slice) { if (!a.check_shared_size()) raise_shared_size_mismatch(); scitbx::boost_python::adapted_slice a_sl(slice, a.size()); af::shared_plain result(af::reserve(a_sl.size)); for(long i=a_sl.start;i!=a_sl.stop;i+=a_sl.step) { result.push_back(a[i]); } return f_t(result, flex_grid<>(result.size())); } static versa > getitem_nd_slice( af::const_ref > const& self, small const& slices) { small dim = self.accessor().all(); small slices_simple; for (unsigned i=0; i(self, slices_simple); } // Not intended to be called directly from Python static e_t& getitem_fgdit(f_t& a, flex_grid_default_index_type const& i) { if (!a.check_shared_size()) raise_shared_size_mismatch(); if (!a.accessor().is_valid_index(i)) { scitbx::boost_python::raise_index_error(); } return a(i); } static boost::python::object getitem_tuple(boost::python::object& a_obj, boost::python::object obj) { f_t a = boost::python::extract(a_obj)(); PyObject* obj_ptr = obj.ptr(); flex_grid_default_index_type tuple = _getitem_tuple_helper< flex_grid_default_index_type, flex_grid_default_index_type::value_type>(obj_ptr); if (tuple.size()>0) { return a_obj.attr("__getitem_fgdit__")(obj); // return boost::python::object(getitem_fgdit(a, tuple)); } af::small slices = _getitem_tuple_helper, boost::python::slice>(obj_ptr); if (slices.size()>0) { return boost::python::object(getitem_nd_slice(a.const_ref(), slices)); } else { PyErr_SetString(PyExc_TypeError, "Expecting int or slice."); boost::python::throw_error_already_set(); } return boost::python::object(); // it can never reach here } static void setitem_1d(f_t& a, long i, e_t const& x) { if (!a.check_shared_size()) raise_shared_size_mismatch(); std::size_t j = positive_getitem_index(i, a.size()); a[j] = x; } static void setitem_flex_grid( f_t& a, flex_grid_default_index_type const& i, e_t const& x) { if (!a.check_shared_size()) raise_shared_size_mismatch(); if (!a.accessor().is_valid_index(i)) { scitbx::boost_python::raise_index_error(); } a(i) = x; } static void delitem_1d(f_t& a, long i) { base_array_type b = flex_as_base_array(a); std::size_t j = positive_getitem_index(i, b.size()); b.erase(b.begin()+j); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void delitem_1d_slice(f_t& a, boost::python::slice const& slice) { base_array_type b = flex_as_base_array(a); scitbx::boost_python::adapted_slice a_sl(slice, b.size()); SCITBX_ASSERT(a_sl.step == 1); // not implemented e_t* bb = b.begin(); b.erase(bb+a_sl.start, bb+a_sl.stop); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static e_t& front(f_t& a) { if (!a.check_shared_size()) raise_shared_size_mismatch(); if (a.size() == 0) scitbx::boost_python::raise_index_error(); return a.front(); } static e_t& back(f_t& a) { if (!a.check_shared_size()) raise_shared_size_mismatch(); if (a.size() == 0) scitbx::boost_python::raise_index_error(); return a.back(); } static void fill(f_t& a, e_t const& x) { if (!a.check_shared_size()) raise_shared_size_mismatch(); a.fill(x); } static void reserve(f_t& a, std::size_t sz) { if (!a.check_shared_size()) raise_shared_size_mismatch(); a.reserve(sz); } static f_t deep_copy(f_t const& a) { if (!a.check_shared_size()) raise_shared_size_mismatch(); return a.deep_copy(); } static f_t shallow_copy(f_t const& a) { if (!a.check_shared_size()) raise_shared_size_mismatch(); return a; } static f_t as_1d(f_t const& a) { if (!a.check_shared_size()) raise_shared_size_mismatch(); SCITBX_ASSERT(!a.accessor().is_padded()); return f_t(a, flex_grid<>(a.size())); } static void assign(f_t& a, std::size_t sz, e_t const& x) { base_array_type b = flex_as_base_array(a); b.assign(sz, x); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void append(f_t& a, e_t const& x) { base_array_type b = flex_as_base_array(a); b.push_back(x); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void pop_back(f_t& a) { base_array_type b = flex_as_base_array(a); if (b.size() == 0) scitbx::boost_python::raise_index_error(); b.pop_back(); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void insert_i_x(f_t& a, long i, e_t const& x) { base_array_type b = flex_as_base_array(a); std::size_t j = positive_getitem_index(i, b.size(), true); b.insert(b.begin()+j, x); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void insert_i_n_x(f_t& a, long i, std::size_t n, e_t const& x) { base_array_type b = flex_as_base_array(a); std::size_t j = positive_getitem_index(i, b.size(), true); b.insert(b.begin()+j, n, x); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void resize_1d_1(f_t& a, std::size_t sz) { base_array_type b = flex_as_base_array(a); b.resize(sz, flex_default_element::get()); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void resize_1d_2(f_t& a, std::size_t sz, e_t const& x) { base_array_type b = flex_as_base_array(a); b.resize(sz, x); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void resize_flex_grid_1(f_t& a, flex_grid<> const& grid) { a.resize(grid, flex_default_element::get()); } static void resize_flex_grid_2(f_t& a, flex_grid<> const& grid, e_t const& x) { a.resize(grid, x); } static void reshape(f_t& a, flex_grid<> const& grid) { SCITBX_ASSERT(grid.size_1d() == a.size()); a.resize(grid, flex_default_element::get()); } static void clear(f_t& a) { base_array_type b = flex_as_base_array(a); b.clear(); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static void extend(f_t& a, f_t const& other) { base_array_type b = flex_as_base_array(a); assert_0_based_1d(other.accessor()); b.insert(b.end(), other.begin(), other.end()); a.resize( flex_grid<>(b.size()), flex_default_element::get()); } static shared concatenate( af::const_ref const& self, af::const_ref const& other) { shared result((af::reserve(self.size()+other.size()))); result.insert(result.end(), self.begin(), self.end()); result.insert(result.end(), other.begin(), other.end()); return result; } static shared reversed( af::const_ref const& self) { shared result((af::reserve(self.size()))); for(std::size_t i=self.size();i>0;) { i--; result.push_back(self[i]); } return result; } static boost::python::object set_selected_bool_a( boost::python::object flex_object, af::const_ref const& flags, af::const_ref const& new_values) { boost::python::extract > a_proxy(flex_object); af::ref a = a_proxy(); SCITBX_ASSERT(a.size() == flags.size()); if (new_values.size() == flags.size()) { e_t* ai = a.begin(); const bool* fi = flags.begin(); const e_t* ni = new_values.begin(); const e_t* ne = new_values.end(); while (ni != ne) { if (*fi++) *ai = *ni; ai++; ni++; } } else { std::size_t i_new_value = 0; for(std::size_t i=0;i > const& flags, e_t const& new_value) { boost::python::extract > > a_proxy(flex_object); af::ref > a = a_proxy(); SCITBX_ASSERT(a.accessor() == flags.accessor()); for(std::size_t i=0;i static boost::python::object set_selected_unsigned_a( boost::python::object const& flex_object, af::const_ref const& indices, af::const_ref const& new_values) { boost::python::extract > a_proxy(flex_object); af::ref a = a_proxy(); SCITBX_ASSERT(indices.size() == new_values.size()); for(std::size_t i=0;i static boost::python::object set_selected_unsigned_s( boost::python::object const& flex_object, af::const_ref const& indices, e_t const& new_value) { boost::python::extract > a_proxy(flex_object); af::ref a = a_proxy(); for(std::size_t i=0;i static boost::python::object copy_selected_unsigned_a( boost::python::object const& flex_object, af::const_ref const& indices, af::const_ref const& new_values) { boost::python::extract > a_proxy(flex_object); af::ref a = a_proxy(); SCITBX_ASSERT(a.size() == new_values.size()); for(std::size_t i=0;i result(a.size(), init_functor_null()); for(std::size_t i=0;i first_index_a_s(f_t const& a, e_t x) { return first_index(a, std::bind2nd(std::equal_to(), x)); } static boost::optional last_index_a_s(f_t const& a, e_t x) { return last_index(a, std::bind2nd(std::equal_to(), x)); } static f_t neg_a(f_t const& a) { return -a; } static f_t add_a_a(f_t const& a1, f_t const& a2) { return a1 + a2; } static f_t sub_a_a(f_t const& a1, f_t const& a2) { return a1 - a2; } static f_t mul_a_a(f_t const& a1, f_t const& a2) { return a1 * a2; } static f_t div_a_a(f_t const& a1, f_t const& a2) { return a1 / a2; } static f_t mod_a_a(f_t const& a1, f_t const& a2) { return a1 % a2; } static f_t add_a_s(f_t const& a1, e_t const& a2) { return a1 + a2; } static f_t sub_a_s(f_t const& a1, e_t const& a2) { return a1 - a2; } static f_t rsub_a_s(f_t const& a2, e_t const& a1) { return a1 - a2; } static f_t mul_a_s(f_t const& a1, e_t const& a2) { return a1 * a2; } static f_t div_a_s(f_t const& a1, e_t const& a2) { return a1 / a2; } static f_t rdiv_a_s(f_t const& a2, e_t const& a1) { return a1 / a2; } static f_t mod_a_s(f_t const& a1, e_t const& a2) { return a1 % a2; } static f_t rmod_a_s(f_t const& a2, e_t const& a1) { return a1 % a2; } static f_t iadd_a_a(f_t& a1, f_t const& a2) { return a1 += a2; } static f_t isub_a_a(f_t& a1, f_t const& a2) { return a1 -= a2; } static f_t imul_a_a(f_t& a1, f_t const& a2) { return a1 *= a2; } static f_t idiv_a_a(f_t& a1, f_t const& a2) { return a1 /= a2; } static f_t imod_a_a(f_t& a1, f_t const& a2) { return a1 %= a2; } static f_t iadd_a_s(f_t& a1, e_t const& a2) { return a1 += a2; } static f_t isub_a_s(f_t& a1, e_t const& a2) { return a1 -= a2; } static f_t imul_a_s(f_t& a1, e_t const& a2) { return a1 *= a2; } static f_t idiv_a_s(f_t& a1, e_t const& a2) { return a1 /= a2; } static f_t imod_a_s(f_t& a1, e_t const& a2) { return a1 %= a2; } static bool all_eq_a_a(f_t const& a1, f_t const& a2) { return a1.all_eq(a2); } static bool all_ne_a_a(f_t const& a1, f_t const& a2) { return a1.all_ne(a2); } static bool all_lt_a_a(f_t const& a1, f_t const& a2) { return a1.all_lt(a2); } static bool all_gt_a_a(f_t const& a1, f_t const& a2) { return a1.all_gt(a2); } static bool all_le_a_a(f_t const& a1, f_t const& a2) { return a1.all_le(a2); } static bool all_ge_a_a(f_t const& a1, f_t const& a2) { return a1.all_ge(a2); } static bool all_eq_a_s(f_t const& a1, e_t const& a2) { return a1.all_eq(a2); } static bool all_ne_a_s(f_t const& a1, e_t const& a2) { return a1.all_ne(a2); } static bool all_lt_a_s(f_t const& a1, e_t const& a2) { return a1.all_lt(a2); } static bool all_gt_a_s(f_t const& a1, e_t const& a2) { return a1.all_gt(a2); } static bool all_le_a_s(f_t const& a1, e_t const& a2) { return a1.all_le(a2); } static bool all_ge_a_s(f_t const& a1, e_t const& a2) { return a1.all_ge(a2); } static int order_a_a(f_t const& a1, f_t const& a2) { return order(a1, a2); } static flex_bool eq_a_a(f_t const& a1, f_t const& a2) { return a1 == a2; } #if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 96 static flex_bool ne_a_a(f_t const& a1, f_t const& a2) { if (a1.size() != a2.size()) throw_range_error(); shared_plain result(a1.size(), init_functor_null()); for(std::size_t i=0;i >(result, a1.accessor()); } #else static flex_bool ne_a_a(f_t const& a1, f_t const& a2) { return a1 != a2; } #endif static flex_bool lt_a_a(f_t const& a1, f_t const& a2) { return a1 < a2; } static flex_bool gt_a_a(f_t const& a1, f_t const& a2) { return a1 > a2; } static flex_bool le_a_a(f_t const& a1, f_t const& a2) { return a1 <= a2; } static flex_bool ge_a_a(f_t const& a1, f_t const& a2) { return a1 >= a2; } static flex_bool eq_a_s(f_t const& a1, e_t const& a2) { return a1 == a2; } static flex_bool ne_a_s(f_t const& a1, e_t const& a2) { return a1 != a2; } static flex_bool lt_a_s(f_t const& a1, e_t const& a2) { return a1 < a2; } static flex_bool gt_a_s(f_t const& a1, e_t const& a2) { return a1 > a2; } static flex_bool le_a_s(f_t const& a1, e_t const& a2) { return a1 <= a2; } static flex_bool ge_a_s(f_t const& a1, e_t const& a2) { return a1 >= a2; } static f_t abs_a(f_t const& a) { return absolute(a); } static f_t pow2_a(f_t const& a) { return pow2(a); } static f_t fmod_a_s(f_t const& a1, e_t const& a2) { return fmod(a1, a2); } static f_t fmod_positive_a_s(f_t const& a1, e_t const& a2) { return fmod_positive(a1, a2); } static f_t pow_a_s(f_t const& a, e_t const& exponent) { return pow(a, exponent); } static f_t atan2_a_a(f_t const& a1, f_t const& a2) { return atan2(a1, a2); } static f_t acos_a(f_t const& a) { return acos(a); } static f_t cos_a(f_t const& a) { return cos(a); } static f_t tan_a(f_t const& a) { return tan(a); } static f_t asin_a(f_t const& a) { return asin(a); } static f_t cosh_a(f_t const& a) { return cosh(a); } static f_t tanh_a(f_t const& a) { return tanh(a); } static f_t atan_a(f_t const& a) { return atan(a); } static f_t exp_a(f_t const& a) { return exp(a); } static f_t sin_a(f_t const& a) { return sin(a); } static f_t fabs_a(f_t const& a) { return fabs(a); } static f_t log_a(f_t const& a) { return log(a); } static f_t sinh_a(f_t const& a) { return sinh(a); } static f_t ceil_a(f_t const& a) { return ceil(a); } static f_t floor_a(f_t const& a) { return floor(a); } static f_t log10_a(f_t const& a) { return log10(a); } static f_t sqrt_a(f_t const& a) { return sqrt(a); } static std::size_t max_index_a(f_t const& a) { return max_index(a); } static std::size_t min_index_a(f_t const& a) { return min_index(a); } static e_t max_a(f_t const& a) { return max(a); } static e_t min_a(f_t const& a) { return min(a); } static e_t max_absolute_a(f_t const& a) { return max_absolute(a); } static e_t sum_a(f_t const& a) { return sum(a); } static e_t sum_sq_a(f_t const& a) { return sum_sq(a); } static e_t product_a(f_t const& a) { return product(a); } static e_t norm_a(f_t const& a) { return norm(a.const_ref()); } static e_t mean_a(f_t const& a) { return mean(a); } static e_t mean_sq_a(f_t const& a) { return mean_sq(a); } static e_t mean_weighted_a_a(f_t const& a1, f_t const& a2) { return mean_weighted(a1, a2); } static e_t mean_sq_weighted_a_a(f_t const& a1, f_t const& a2) { return mean_sq_weighted(a1, a2); } typedef boost::python::class_ > class_f_t; static class_f_t plain(std::string const& python_name) { using namespace boost::python; scitbx::boost_python::container_conversions::from_python_sequence< shared_plain, scitbx::boost_python::container_conversions ::variable_capacity_policy>(); scitbx::boost_python::container_conversions::from_python_sequence< shared, scitbx::boost_python::container_conversions ::variable_capacity_policy>(); shared_flex_conversions(); ref_flex_conversions(); flex_1d_from_flex(); class_f_t result(python_name.c_str()); result .def(init const&, optional >()) .def(init >()) .def(init const&>()) .def("element_size", element_size) .staticmethod("element_size") .def("accessor", accessor) .def("nd", nd) .def("is_0_based", is_0_based) .def("origin", origin) .def("all", all) .def("last", last_0) .def("last", last_1) .def("is_padded", is_padded) .def("focus", focus_0) .def("focus", focus_1) .def("focus_size_1d", focus_size_1d) .def("is_trivial_1d", is_trivial_1d) .def("shift_origin", shift_origin) .def("id", id) .def("size", size) .def("__len__", size) .def("capacity", capacity) .def("__getitem__", getitem_tuple) // must be before other __getitem__ .def("__getitem__", getitem_1d_slice) .def("__getitem__", getitem_1d, GetitemReturnValuePolicy()) .def("__getitem_fgdit__", getitem_fgdit, GetitemReturnValuePolicy()) .def("__setitem__", setitem_1d) .def("__setitem__", setitem_flex_grid) .def("__delitem__", delitem_1d) .def("__delitem__", delitem_1d_slice) .def("front", front, GetitemReturnValuePolicy()) .def("back", back, GetitemReturnValuePolicy()) .def("fill", fill) .def("reserve", reserve) .def("deep_copy", deep_copy) .def("shallow_copy", shallow_copy) .def("as_1d", as_1d) .def("assign", assign) .def("pop_back", pop_back) .def("append", append) .def("insert", insert_i_x) .def("insert", insert_i_n_x) .def("resize", resize_1d_1) .def("resize", resize_1d_2) .def("resize", resize_flex_grid_1) .def("resize", resize_flex_grid_2) .def("reshape", reshape) .def("clear", clear) .def("extend", extend) .def("concatenate", concatenate) .def("reversed", reversed) ; select_wrappers::wrap(result); result .def("set_selected", set_selected_bool_a) .def("set_selected", set_selected_bool_s) .def("set_selected", (object(*)( object const&, af::const_ref const&, af::const_ref const&)) set_selected_unsigned_a) .def("set_selected", (object(*)( object const&, af::const_ref const&, e_t const&)) set_selected_unsigned_s) .def("copy_selected", (object(*)( object const&, af::const_ref const&, af::const_ref const&)) copy_selected_unsigned_a) #if !defined(BOOST_ADAPTBX_TYPE_ID_SIZE_T_EQ_UNSIGNED) .def("set_selected", (object(*)( object const&, af::const_ref const&, af::const_ref const&)) set_selected_unsigned_a) .def("set_selected", (object(*)( object const&, af::const_ref const&, e_t const&)) set_selected_unsigned_s) .def("copy_selected", (object(*)( object const&, af::const_ref const&, af::const_ref const&)) copy_selected_unsigned_a) #endif ; return result; } static class_f_t ordered(std::string const& python_name, boost::python::object const& flex_root_scope) { { using namespace boost::python; scope local_scope(flex_root_scope); def("order", order_a_a); def("first_index", first_index_a_s); def("last_index", last_index_a_s); } return plain(python_name) .def("__eq__", eq_a_a) .def("__ne__", ne_a_a) .def("__eq__", eq_a_s) .def("__ne__", ne_a_s) .def("all_eq", all_eq_a_a) .def("all_ne", all_ne_a_a) .def("all_eq", all_eq_a_s) .def("all_ne", all_ne_a_s) ; } static class_f_t numeric_common(std::string const& python_name, boost::python::object const& flex_root_scope) { { boost::python::scope local_scope(flex_root_scope); boost::python::def("sum", sum_a); boost::python::def("sum_sq", sum_sq_a); boost::python::def("product", product_a); } return plain(python_name) .def("count", count) .def("__neg__", neg_a) .def("__add__", add_a_a) .def("__sub__", sub_a_a) .def("__mul__", mul_a_a) .def("__div__", div_a_a) .def("__truediv__", div_a_a) .def("__add__", add_a_s) .def("__radd__", add_a_s) .def("__sub__", sub_a_s) .def("__rsub__", rsub_a_s) .def("__mul__", mul_a_s) .def("__rmul__", mul_a_s) .def("__div__", div_a_s) .def("__truediv__", div_a_s) .def("__rdiv__", rdiv_a_s) .def("__rtruediv__", rdiv_a_s) .def("__iadd__", iadd_a_a) .def("__isub__", isub_a_a) .def("__imul__", imul_a_a) .def("__idiv__", idiv_a_a) .def("__itruediv__", idiv_a_a) .def("__iadd__", iadd_a_s) .def("__isub__", isub_a_s) .def("__imul__", imul_a_s) .def("__idiv__", idiv_a_s) .def("__itruediv__", idiv_a_s) .def("__eq__", eq_a_a) .def("__ne__", ne_a_a) .def("__eq__", eq_a_s) .def("__ne__", ne_a_s) .def("all_eq", all_eq_a_a) .def("all_ne", all_ne_a_a) .def("all_eq", all_eq_a_s) .def("all_ne", all_ne_a_s) ; } static class_f_t numeric_no_pow(std::string const& python_name, boost::python::object const& flex_root_scope) { { using namespace boost::python; scope local_scope(flex_root_scope); def("min_index", min_index_a); def("max_index", max_index_a); def("min", min_a); def("max", max_a); def("max_absolute", max_absolute_a); def("pow2", pow2_a); def("order", order_a_a); def("first_index", first_index_a_s); def("last_index", last_index_a_s); } return numeric_common(python_name, flex_root_scope) .def("as_double", as_double) .def("__lt__", lt_a_a) .def("__gt__", gt_a_a) .def("__le__", le_a_a) .def("__ge__", ge_a_a) .def("__lt__", lt_a_s) .def("__gt__", gt_a_s) .def("__le__", le_a_s) .def("__ge__", ge_a_s) .def("all_lt", all_lt_a_a) .def("all_gt", all_gt_a_a) .def("all_le", all_le_a_a) .def("all_ge", all_ge_a_a) .def("all_lt", all_lt_a_s) .def("all_gt", all_gt_a_s) .def("all_le", all_le_a_s) .def("all_ge", all_ge_a_s) .def("norm_inf", max_absolute_a) ; } static class_f_t numeric(std::string const& python_name, boost::python::object const& flex_root_scope) { { boost::python::scope local_scope(flex_root_scope); boost::python::def("abs", abs_a); boost::python::def("pow", pow_a_s); boost::python::def("fmod", fmod_a_s); boost::python::def("fmod_positive", fmod_positive_a_s); boost::python::def("atan2", atan2_a_a); boost::python::def("acos", acos_a); boost::python::def("cos", cos_a); boost::python::def("tan", tan_a); boost::python::def("asin", asin_a); boost::python::def("cosh", cosh_a); boost::python::def("tanh", tanh_a); boost::python::def("atan", atan_a); boost::python::def("exp", exp_a); boost::python::def("sin", sin_a); boost::python::def("fabs", fabs_a); boost::python::def("log", log_a); boost::python::def("sinh", sinh_a); boost::python::def("ceil", ceil_a); boost::python::def("floor", floor_a); boost::python::def("log10", log10_a); boost::python::def("sqrt", sqrt_a); boost::python::def("mean", mean_a); boost::python::def("mean_sq", mean_sq_a); boost::python::def("mean_weighted", mean_weighted_a_a); boost::python::def("mean_sq_weighted", mean_sq_weighted_a_a); } return numeric_no_pow(python_name, flex_root_scope) .def("norm", norm_a) .def("__pow__", pow_a_s) .def("__abs__", abs_a) ; } static class_f_t integer(std::string const& python_name, boost::python::object const& flex_root_scope) { return numeric_no_pow(python_name, flex_root_scope) .def("__mod__", mod_a_a) .def("__mod__", mod_a_s) .def("__rmod__", rmod_a_s) .def("__imod__", imod_a_a) .def("__imod__", imod_a_s) ; } static class_f_t signed_integer(std::string const& python_name, boost::python::object const& flex_root_scope) { { boost::python::scope local_scope(flex_root_scope); boost::python::def("abs", abs_a); } return integer(python_name, flex_root_scope); } }; }}} // namespace scitbx::af::boost_python #endif // SCITBX_ARRAY_FAMILY_BOOST_PYTHON_FLEX_WRAPPER_H