From 4e9e72b48fa43401c9600d261983f1cd53988a50 Mon Sep 17 00:00:00 2001
From: Thomas Purcell <purcell@fhi-berlin.mpg.de>
Date: Sat, 4 Jul 2020 11:07:15 +0200
Subject: [PATCH] Update bindings to include __pow__, __repr__, and __str__
 explicitly

Make it easier to work with units and models in python
---
 src/descriptor_identifier/Model/Model.cpp |  3 ++-
 src/feature_creation/units/Unit.cpp       | 33 ++++++++++++++++++++---
 src/feature_creation/units/Unit.hpp       | 16 +++++++++++
 3 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/src/descriptor_identifier/Model/Model.cpp b/src/descriptor_identifier/Model/Model.cpp
index 268b0705..bc313a73 100644
--- a/src/descriptor_identifier/Model/Model.cpp
+++ b/src/descriptor_identifier/Model/Model.cpp
@@ -173,7 +173,8 @@ void Model::register_python()
     class_<Model>("Model", init<std::vector<double>, std::vector<double>, std::vector<model_node_ptr>, std::vector<int>, std::vector<int>>())
         .def("predict", &Model::predict)
         .def("fit", &Model::predict_train)
-        // .def(str(self))
+        .def("__str__", &Model::toString)
+        .def("__repr__", &Model::toString)
         .def_readonly("_n_samp_train", &Model::_n_samp_train)
         .def_readonly("_n_samp_test", &Model::_n_samp_test)
         .def_readonly("_n_dim", &Model::_n_dim)
diff --git a/src/feature_creation/units/Unit.cpp b/src/feature_creation/units/Unit.cpp
index 61637af2..3fbcda80 100644
--- a/src/feature_creation/units/Unit.cpp
+++ b/src/feature_creation/units/Unit.cpp
@@ -106,6 +106,31 @@ Unit Unit::operator/(Unit unit_2)
     return Unit(to_out);
 }
 
+Unit& Unit::operator*=(Unit unit_2)
+{
+    for(auto& el : unit_2.dct())
+    {
+        if(_dct.count(el.first) > 0)
+            _dct[el.first] += el.second;
+        else
+            _dct[el.first] = el.second;
+    }
+    return *this;
+}
+
+Unit& Unit::operator/=(Unit unit_2)
+{
+    for(auto& el : unit_2.dct())
+    {
+        if(_dct.count(el.first) > 0)
+            _dct[el.first] -= el.second;
+        else
+            _dct[el.first] = -1.0 * el.second;
+    }
+
+    return *this;
+}
+
 Unit Unit::operator^(double power)
 {
     std::map<std::string, double> to_out = dct();
@@ -158,7 +183,6 @@ std::ostream& operator<< (std::ostream& outStream, const Unit& unit)
     return outStream;
 }
 
-
 void Unit::register_python()
 {
     using namespace boost::python;
@@ -166,12 +190,15 @@ void Unit::register_python()
         .def(init<std::map<std::string, double>>())
         .def(init<std::string>())
         .def(init<Unit&>())
-        // .def(str(self))
+        .def("__str__", &Unit::toString)
+        .def("__repr__", &Unit::toString)
         .def("inverse", &Unit::inverse)
         .def(self * self)
         .def(self / self)
+        .def(self *= self)
+        .def(self /= self)
         .def(self == self)
         .def(self != self)
-        // .def(pow(self, other<double>))
+        .def("__pow__", &Unit::operator^)
         .add_property("dct", &Unit::dct);
 }
\ No newline at end of file
diff --git a/src/feature_creation/units/Unit.hpp b/src/feature_creation/units/Unit.hpp
index 94f90747..3848d3a8 100644
--- a/src/feature_creation/units/Unit.hpp
+++ b/src/feature_creation/units/Unit.hpp
@@ -74,6 +74,22 @@ public:
      */
     Unit operator/(Unit unit_2);
 
+    /**
+     * @brief Multiply operator for units
+     *
+     * @param unit_2 The second unit to multiply by
+     * @return The product of this unit with unit_2
+     */
+    Unit& operator*=(Unit unit_2);
+
+    /**
+     * @brief Divide operator for units
+     *
+     * @param unit_2 The second unit to divide by
+     * @return The quotient of this unit with unit_2
+     */
+    Unit& operator/=(Unit unit_2);
+
     /**
      * @brief Exponentiation operator for units
      *
-- 
GitLab