From a6b2c6a3f4a08e17b8a7ced202777fa478ae596d Mon Sep 17 00:00:00 2001 From: Bruno Turcksin Date: Tue, 11 Apr 2017 09:41:03 -0400 Subject: [PATCH] Add python wrapper functions to Point. --- .../python-bindings/include/point_wrapper.h | 100 +++++- .../python-bindings/source/export_point.cc | 60 +++- .../python-bindings/source/point_wrapper.cc | 340 +++++++++++++++++- 3 files changed, 495 insertions(+), 5 deletions(-) diff --git a/contrib/python-bindings/include/point_wrapper.h b/contrib/python-bindings/include/point_wrapper.h index 7c266fa007..8ea77d04fb 100644 --- a/contrib/python-bindings/include/point_wrapper.h +++ b/contrib/python-bindings/include/point_wrapper.h @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2016 by the deal.II authors +// Copyright (C) 2016 - 2017 by the deal.II authors // // This file is part of the deal.II library. // @@ -20,6 +20,8 @@ #ifdef DEAL_II_WITH_CXX11 +#include + #include DEAL_II_NAMESPACE_OPEN @@ -40,6 +42,12 @@ namespace python */ PointWrapper(boost::python::list list); + /** + * Constructor. Intialize PointWrapper using a Point. + */ + template + PointWrapper(const Point &p); + /** * Copy constructor. */ @@ -50,12 +58,89 @@ namespace python */ ~PointWrapper(); + /** + * Return the Euclidean distance of this point to the point p, i.e., the + * l2_norm of the difference between the vectors representing the two + * points. + */ + double distance(const PointWrapper &p) const; + + /** + * Return the l2_norm of the vector connecting the origin to the point. + */ + double norm() const; + + /** + * Return the sum of the absolute squares of all entries. + */ + double norm_square() const; + /** * Assignment operator. The dimension of the point is changed if it is * different than the one of @p other. */ PointWrapper &operator= (const PointWrapper &other); + /** + * Test for inequality of two points. + */ + bool operator!= (const PointWrapper &p) const; + + /** + * Test for equality of two tensors. + */ + bool operator== (const PointWrapper &p) const; + + /** + * Return the scalar product of the vectors representing two points. + */ + double operator* (const PointWrapper &p) const; + + /** + * Add an offset to a point. + */ + PointWrapper operator+(const PointWrapper &) const; + + /** + * Subtract two points. + */ + PointWrapper operator-(const PointWrapper &) const; + + /** + * The opposite point. + */ + PointWrapper operator-() const; + + /** + * Divide the coordinates of the point by a factor. + */ + PointWrapper operator/(const double factor) const; + + /** + * Multiply the coordinates of the point by a factor. + */ + PointWrapper operator* (const double factor) const; + + /** + * Add another point. + */ + PointWrapper& operator+= (const PointWrapper &p); + + /** + * Subtract another point. + */ + PointWrapper& operator-= (const PointWrapper &p); + + /** + * Scale the coordinates of the point by factor. + */ + PointWrapper& operator*= (const double factor); + + /** + * Scale the coordinates of the point by 1/factor. + */ + PointWrapper& operator/= (const double factor); + /** * Return the first component of the Point. */ @@ -96,6 +181,11 @@ namespace python */ void *get_point(); + /** + * Return a constant pointer that can be casted to the underlying Point. + */ + const void *get_point() const; + private: /** * Delete the underlying Point and free the memory. @@ -137,6 +227,14 @@ namespace python { return point; } + + + + inline + const void *PointWrapper::get_point() const + { + return point; + } } DEAL_II_NAMESPACE_CLOSE diff --git a/contrib/python-bindings/source/export_point.cc b/contrib/python-bindings/source/export_point.cc index 61b840fe82..d79f6c36b1 100644 --- a/contrib/python-bindings/source/export_point.cc +++ b/contrib/python-bindings/source/export_point.cc @@ -25,16 +25,70 @@ DEAL_II_NAMESPACE_OPEN namespace python { + const char distance_docstring [] = + "Return the Euclidean distance of this point to the point p \n" + ; + + + + const char norm_docstring [] = + "Return the L2 norm of the vector connecting the origin to the point \n" + ; + + + + const char norm_square_docstring [] = + "Return the sum of the absolute squares of all entries \n" + ; + + + + const char get_x_docstring [] = + "Get the x component of the point \n" + ; + + + + const char get_y_docstring [] = + "Get the y component of the point \n" + ; + + + + const char get_z_docstring [] = + "Get the z component of the point \n" + ; + + + void export_point() { boost::python::class_ ("Point", boost::python::init()) + .def("distance", &PointWrapper::distance, distance_docstring, + boost::python::args("self", "p")) + .def("norm", &PointWrapper::norm, norm_docstring, + boost::python::args("self")) + .def("norm_square", &PointWrapper::norm_square, norm_square_docstring, + boost::python::args("self")) + .def(boost::python::self != boost::python::self) + .def(boost::python::self == boost::python::self) + .def(boost::python::self * boost::python::self) + .def(boost::python::self + boost::python::self) + .def(boost::python::self - boost::python::self) + .def(- boost::python::self) + .def(boost::python::self / float()) + .def(boost::python::self * float()) + .def(boost::python::self += boost::python::self) + .def(boost::python::self -= boost::python::self) + .def(boost::python::self *= float()) + .def(boost::python::self /= float()) .add_property("x", &PointWrapper::get_x, &PointWrapper::set_x, - "Get the x component of the point.") + get_x_docstring) .add_property("y", &PointWrapper::get_y, &PointWrapper::set_y, - "Get the y component of the point.") + get_y_docstring) .add_property("z", &PointWrapper::get_z, &PointWrapper::set_z, - "Get the z component of the point."); + get_z_docstring); } } diff --git a/contrib/python-bindings/source/point_wrapper.cc b/contrib/python-bindings/source/point_wrapper.cc index 3fb1863090..d58220b048 100644 --- a/contrib/python-bindings/source/point_wrapper.cc +++ b/contrib/python-bindings/source/point_wrapper.cc @@ -17,12 +17,125 @@ #ifdef DEAL_II_WITH_CXX11 -#include DEAL_II_NAMESPACE_OPEN namespace python { + namespace internal + { + template + double distance(const Point & p1, + const Point & p2) + { + return p1.distance(p2); + } + + + + template + bool not_equal(const Point &p1, + const Point &p2) + { + return (p1 != p2); + } + + + + template + bool equal(const Point &p1, + const Point &p2) + { + return (p1 == p2); + } + + + + template + double dot_product (const Point &p1, + const Point &p2) + { + return p1*p2; + } + + + + template + Point add_points(const Point &p1, + const Point &p2) + { + return p1+p2; + } + + + + template + Point subtract_point(const Point &p1, + const Point &p2) + { + if (dim == 2) + return Point(p1[0]-p2[0], p1[1]-p2[1]); + else + return Point(p1[0]-p2[0], p1[1]-p2[1], p1[2]-p2[2]); + } + + + + template + Point opposite_point(const Point &p) + { + return -p; + } + + + + template + Point divide_point(const Point &p, double factor) + { + return p/factor; + } + + + + template + Point multiply_point(const Point &p, double factor) + { + return p*factor; + } + + + + template + void add_and_set(Point &p1, const Point &p2) + { + p1 += p2; + } + + + + template + void subtract_and_set(Point &p1, const Point &p2) + { + p1 -= p2; + } + + + + template + void multiply_and_set(Point &p, double factor) + { + p *= factor; + } + + + + template + void divide_and_set(Point &p, double factor) + { + p /= factor; + } + } + PointWrapper::PointWrapper() : dim(-1), @@ -47,6 +160,19 @@ namespace python + template + PointWrapper::PointWrapper(const Point &p) + { + dim = d; + if (dim == 2) + point = new Point<2>(p[0],p[1]); + + else + point = new Point<3>(p[0],p[1],p[2]); + } + + + PointWrapper::PointWrapper(const PointWrapper &other) { copy(other); @@ -62,6 +188,41 @@ namespace python + double PointWrapper::distance(const PointWrapper &p) const + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + return internal::distance(*static_cast*>(point), + *static_cast*>(p.get_point())); + else + return internal::distance(*static_cast*>(point), + *static_cast*>(p.get_point())); + } + + + + double PointWrapper::norm() const + { + if (dim == 2) + return static_cast*>(point)->norm(); + else + return static_cast*>(point)->norm(); + } + + + + double PointWrapper::norm_square() const + { + if (dim == 2) + return static_cast*>(point)->norm_square(); + else + return static_cast*>(point)->norm_square(); + } + + + PointWrapper &PointWrapper::operator= (const PointWrapper &other) { clear(); @@ -72,6 +233,183 @@ namespace python + bool PointWrapper::operator!= (const PointWrapper &p) const + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + return internal::not_equal(*static_cast*>(point), + *static_cast*>(p.get_point())); + else + return internal::not_equal(*static_cast*>(point), + *static_cast*>(p.get_point())); + } + + + + bool PointWrapper::operator== (const PointWrapper &p) const + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + return internal::equal(*static_cast*>(point), + *static_cast*>(p.get_point())); + else + return internal::equal(*static_cast*>(point), + *static_cast*>(p.get_point())); + } + + + + double PointWrapper::operator* (const PointWrapper &p) const + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + return internal::dot_product(*static_cast*>(point), + *static_cast*>(p.get_point())); + else + return internal::dot_product(*static_cast*>(point), + *static_cast*>(p.get_point())); + } + + + + PointWrapper PointWrapper::operator+ (const PointWrapper &p) const + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + return PointWrapper(internal::add_points( + *static_cast*>(point), + *static_cast*>(p.get_point()))); + else + return PointWrapper(internal::add_points( + *static_cast*>(point), + *static_cast*>(p.get_point()))); + } + + + + PointWrapper PointWrapper::operator- (const PointWrapper &p) const + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + return PointWrapper(internal::subtract_point( + *static_cast*>(point), + *static_cast*>(p.get_point()))); + else + return PointWrapper(internal::subtract_point( + *static_cast*>(point), + *static_cast*>(p.get_point()))); + } + + + + PointWrapper PointWrapper::operator-() const + { + if (dim == 2) + return PointWrapper(internal::opposite_point( + *static_cast*>(point))); + else + return PointWrapper(internal::opposite_point( + *static_cast*>(point))); + } + + + + PointWrapper PointWrapper::operator/(const double factor) const + { + AssertThrow(factor != 0., ExcMessage("Dividing by zero.")); + + if (dim == 2) + return PointWrapper(internal::divide_point( + *static_cast*>(point), factor)); + else + return PointWrapper(internal::divide_point( + *static_cast*>(point), factor)); + } + + + PointWrapper PointWrapper::operator* (const double factor) const + { + + if (dim == 2) + return PointWrapper(internal::multiply_point( + *static_cast*>(point), factor)); + else + return PointWrapper(internal::multiply_point( + *static_cast*>(point), factor)); + } + + + + PointWrapper& PointWrapper::operator+= (const PointWrapper &p) + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + internal::add_and_set(*static_cast*>(point), + *static_cast*>(p.get_point())); + else + internal::add_and_set(*static_cast*>(point), + *static_cast*>(p.get_point())); + + return *this; + } + + + + PointWrapper& PointWrapper::operator-= (const PointWrapper &p) + { + AssertThrow(p.get_dim() == dim, + ExcMessage("The points do not have the same dimension.")); + + if (dim == 2) + internal::subtract_and_set(*static_cast*>(point), + *static_cast*>(p.get_point())); + else + internal::subtract_and_set(*static_cast*>(point), + *static_cast*>(p.get_point())); + + return *this; + } + + + + PointWrapper& PointWrapper::operator*= (const double factor) + { + if (dim == 2) + internal::multiply_and_set(*static_cast*>(point), factor); + else + internal::multiply_and_set(*static_cast*>(point), factor); + + return *this; + } + + + + PointWrapper& PointWrapper::operator/= (const double factor) + { + AssertThrow(factor != 0., ExcMessage("Dividing by zero.")); + + if (dim == 2) + internal::divide_and_set(*static_cast*>(point), factor); + else + internal::divide_and_set(*static_cast*>(point), factor); + + return *this; + } + + + double PointWrapper::get_x() const { if (dim == 2) -- 2.39.5