Commit 922d579b authored by Jason Rhinelander's avatar Jason Rhinelander

Updates for eris master branch

parent 9f046142
......@@ -32,17 +32,12 @@ macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out-of-source buil
set(CMAKE_CXX_FLAGS "-std=c++14 -O2 -Wall -Wextra ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -DERIS_DEBUG")
# Make sure pybind11 exists
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/pybind11/CMakeLists.txt")
add_subdirectory(pybind11)
else()
message(FATAL_ERROR "pybind11/CMakeLists.txt does not exist; try running `git submodule update --init'")
endif()
add_subdirectory(pybind11)
# Eigen: Move semantics were during 3.3 development, and backported in 3.2.7:
find_package(Eigen3 REQUIRED)
if (EIGEN3_VERSION_STRING VERSION_LESS "3.2.7")
message(FATAL_ERROR "Eigen v3.2.7 required, but found v${EIGEN3_VERSION_STRING}")
message(FATAL_ERROR "Eigen v3.2.7+ required, but found v${EIGEN3_VERSION_STRING}")
else()
message(STATUS "Eigen version: ${EIGEN3_VERSION_STRING}")
endif()
......
Subproject commit 68a9989298635c46e08221812e201935c0e613be
Subproject commit e067c5842bf2b55b3f06a6afbe3f1bb3e10fd1e7
......@@ -10,12 +10,20 @@ namespace pyeris {
PYBIND11_PLUGIN(core) {
py::module m("eris", "eris interface for Python -- core functionality");
py::class_<MemberID>(m, "MemberID")
.def(py::init<eris_id_t>())
.def(py::init<SharedMember<Member>>())
.def_property_readonly("id", [](MemberID &m) { return (eris_id_t) m; });
py::implicitly_convertible<eris_id_t, MemberID>();
core::bind_simulation(m);
core::bind_bundles(m);
core::bind_members(m);
py::implicitly_convertible<Member, MemberID>();
return m.ptr();
}
......
......@@ -9,7 +9,7 @@ void bind_simulation(py::module &m) {
py::class_<Simulation, std::shared_ptr<Simulation>> simulation(m, "Simulation");
simulation
.def_static("create", &Simulation::create, "Constructs a new Simulation object")
.def_static("create", []() { return Simulation::create(); }, "Constructs a new Simulation object")
// The C++ versions of these are templated to allow any particular Agent or Agent subclass,
// to save some type conversion, and to ensure that the requested member actually conforms
// to the given type. In Python, these are a bit looser: they always give back the generic
......
......@@ -22,7 +22,7 @@ void bind_bundles(py::module &m) {
new (&bundle) BundleSigned;
for (auto &g : init) bundle.set(g.first, g.second);
}, "Initializes a BundleSigned from a dict of (good,quantity) pairs")
.def("__getitem__", (const double& (BundleSigned::*)(eris_id_t) const) &BundleSigned::operator[], "Accesses the quantity of a given good in the bundle. Returns 0 for goods that are not in the bundle (rather than throwing a KeyError)")
.def("__getitem__", [](BundleSigned &b, MemberID id) { return (double) b[id]; }, "Accesses the quantity of a given good in the bundle. Returns 0 for goods that are not in the bundle (rather than throwing a KeyError)")
.def("__setitem__", &BundleSigned::set, "Sets the quantity of a given good in the bundle.")
.def("__delitem__", [](BundleSigned &bundle, eris_id_t gid) -> void {
if (not bundle.count(gid)) {
......@@ -43,14 +43,16 @@ void bind_bundles(py::module &m) {
.def("positive", &BundleSigned::positive, "Constructs a new Bundle (not BundleSigned) containing all of the strictly positive quantities of this bundle. Goods with a quantity of 0 are not included.")
.def("negative", &BundleSigned::negative, "Constructs a new Bundle (not BundleSigned) containing all of the strictly negative quantities of this bundle, converted to positive values. Goods with a quantity of 0 are not included.")
.def("zeros", &BundleSigned::zeros, "Constructs a new Bundle (not BundleSigned) containing all of the goods that have quantities of exactly 0. Complementary to positive() and negative()")
.def("transfer_approx",
(BundleSigned (BundleSigned::*)(const BundleSigned&, BundleSigned&, double)) &BundleSigned::transferApprox,
.def("transfer",
py::overload_cast<const BundleSigned&, BundleSigned&, double>(&BundleSigned::transfer),
"Transfers approximately the given amount between two bundles. Positive quantities in `amount` are transferred from this bundle into `to`; negative quantities are transferred from `to` into this bundle. `epsilon` is a relative threshold: the individual transfer amounts may be adjusted by this times the initial quantity if doing so would result in exactly 0 post-transfer. This is intended to avoid numerical error that could result in small positive of negative quantities. Returns the bundle actually transferred, which can differ slightly from `amount` because of `epsilon`",
py::arg("amount"), py::arg("to"), py::arg("epsilon") = BundleSigned::default_transfer_epsilon)
.def("transfer_approx",
(BundleSigned (BundleSigned::*)(const BundleSigned&, double)) &BundleSigned::transferApprox,
.def("transfer",
py::overload_cast<const BundleSigned&, double>(&BundleSigned::transfer),
"Transfers approximately the given amount in (for positive quantities) or out (for negative quantities) and returns it. Note that, unlike the three-argument transfer_approx method, this method can only apply `epsilon` adjustments to amounts transferred out of the called-upon bundle, and so the other version is much preferred to transfer between bundles.",
py::arg("amount"), py::arg("epsilon") = BundleSigned::default_transfer_epsilon)
.def("transfer_to", &Bundle::transferTo, "Transfers all quantities held by the caller into the target bundle. Essentially the same as `bundle.transfer(bundle, to)` except that `bundle` will always be cleared, while using `transfer` can leave negligible amounts in `bundle`.",
py::arg("to"), py::arg("epsilon") = BundleSigned::default_transfer_epsilon)
.def("begin_transaction", &BundleSigned::beginTransaction, "Begins a transaction for this bundle, used to ensure that multiple bundle modifications are either entirely succeeded or entirely aborted. While the transaction is in progress, all Bundle changes are stored separately from the pre-transaction values until either abort_transaction() or commit_transaction() is called. If the optional `encompassing` parameter is true, any transactions started during this transaction are effectively ignored",
py::arg("encompassing") = false)
.def("commit_transaction", &BundleSigned::commitTransaction, "Finishes a transaction successfully; the pre-transaction bundle values are discarded.")
......
......@@ -36,8 +36,8 @@ public:
void _removed() {
PYBIND11_OVERLOAD_NAME(void, Base, "_removed", removed);
}
void weakDepRemoved(SharedMember<Member> removed, eris_id_t old_id) override {
PYBIND11_OVERLOAD_NAME(void, Base, "weak_dep_removed", weakDepRemoved, removed, old_id);
void weakDepRemoved(SharedMember<Member> removed) override {
PYBIND11_OVERLOAD_NAME(void, Base, "weak_dep_removed", weakDepRemoved, removed);
}
};
......
......@@ -42,7 +42,7 @@ void bind_position(py::module &m) {
.def(py::self /= double(), "Scales a Position's coefficients")
;
py::implicitly_convertible<std::vector<double>, Position>();
py::implicitly_convertible<py::list, Position>();
}
}}
......@@ -1201,7 +1201,7 @@ class AlgebraicModifiers(Base):
self.assertRaises(BundleNegativityError, self.divmutate, b, -1)
def test_transfer_approx(self):
def test_transfer(self):
a = Bundle({ 1: 999, 2: 9999, 3: 100000})
c = Bundle({ 1: 5000, 2: 40000})
......@@ -1210,14 +1210,14 @@ class AlgebraicModifiers(Base):
aa = a.copy()
cc = c.copy()
aa.transfer_approx(transfer, cc, 1.5e-3)
aa.transfer(transfer, cc, 1.5e-3)
self.assertEqual(aa, Bundle({ 1: 0, 2: 0, 3: 5000}))
self.assertEqual(cc, Bundle({ 1: 5999, 2: 49999, 3: 95000}))
# Try the same thing with a negative transfer
ar = a.copy()
cr = c.copy()
cr.transfer_approx(-transfer, ar, 1.5e-3)
cr.transfer(-transfer, ar, 1.5e-3)
self.assertEqual(ar, Bundle({ 1: 0, 2: 0, 3: 5000}))
self.assertEqual(cr, Bundle({ 1: 5999, 2: 49999, 3: 95000}))
......@@ -1225,7 +1225,7 @@ class AlgebraicModifiers(Base):
# close to 0, which can only happen when the destination starts negative).
an = -BundleSigned(a)
cn = BundleSigned(c)
cn.transfer_approx(transfer, an, 1.5e-3)
cn.transfer(transfer, an, 1.5e-3)
self.assertEqual(an, BundleSigned({ 1: 0, 2: 0, 3: -5000}))
self.assertEqual(cn, BundleSigned({ 1: 4001, 2: 30001, 3: -95000}))
......@@ -1233,7 +1233,7 @@ class AlgebraicModifiers(Base):
ab = BundleSigned({ 1: 999, 2: -9999, 3: 100000, 4: 500})
cb = BundleSigned({ 1: 5000, 2: 40000, 4: 500.5})
cb.transfer_approx(BundleSigned({ 1: -1000, 2: 10000, 3: -95001, 4: 500}), ab, 1.5e-3)
cb.transfer(BundleSigned({ 1: -1000, 2: 10000, 3: -95001, 4: 500}), ab, 1.5e-3)
self.assertEqual(ab, Bundle({ 1: 0, 2: 0, 3: 4999, 4: 1000.5}))
self.assertEqual(cb, Bundle({ 1: 5999, 2: 30001, 3: 95001, 4: 0}))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment