Skip to content

Commit

Permalink
Minor stylystic updates to pyqpp
Browse files Browse the repository at this point in the history
Signed-off-by: Vlad Gheorghiu <[email protected]>
  • Loading branch information
vsoftco committed Jan 6, 2025
1 parent c9afdf6 commit 9f0ea90
Show file tree
Hide file tree
Showing 6 changed files with 756 additions and 715 deletions.
927 changes: 466 additions & 461 deletions pyqpp/include/pyqpp/classes/qcircuit_bind.hpp

Large diffs are not rendered by default.

67 changes: 34 additions & 33 deletions pyqpp/include/pyqpp/classes/qdummy_engine_bind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,40 +46,41 @@ void declare_QDummyEngine(py::module& m) {
using DummyEngineType =
std::conditional_t<std::is_same_v<T, ket>, QKetDummyEngine,
QDensityDummyEngine>;
py::class_<DummyEngineType>(m, pyname.c_str())
.def(py::init<const QCircuit&>(), py::keep_alive<1, 2>())
.def("execute", py::overload_cast<idx>(&DummyEngineType::execute),
"Executes the entire quantum circuit description",
py::arg("reps") = 1)
.def(
"get_circuit",
[](const DummyEngineType& qe) { return qe.get_circuit(); },
"Underlying quantum circuit description")
.def("get_state", &DummyEngineType::get_state,
"Underlying quantum state")
.def("set_state", &DummyEngineType::set_state,
"Sets the underlying quantum state", py::arg("state"))
.def("to_JSON", &DummyEngineType::to_JSON,
"State of the engine in JSON format",
py::arg("enclosed_in_curly_brackets") = true)
.def("traits_get_name", &DummyEngineType::traits_get_name,
"Engine name")
.def("traits_is_noisy", &DummyEngineType::traits_is_noisy,
"Noisy engine?")
.def("traits_is_pure", &DummyEngineType::traits_is_pure,
"Pure state engine?")
auto pyQDummyEngine = py::class_<DummyEngineType>(m, pyname.c_str());
pyQDummyEngine.def(py::init<const QCircuit&>(), py::keep_alive<1, 2>());
pyQDummyEngine.def(
"execute", py::overload_cast<idx>(&DummyEngineType::execute),
"Executes the entire quantum circuit description", py::arg("reps") = 1);
pyQDummyEngine.def(
"get_circuit",
[](const DummyEngineType& qe) { return qe.get_circuit(); },
"Underlying quantum circuit description");
pyQDummyEngine.def("get_state", &DummyEngineType::get_state,
"Underlying quantum state");
pyQDummyEngine.def("set_state", &DummyEngineType::set_state,
"Sets the underlying quantum state", py::arg("state"));
pyQDummyEngine.def("to_JSON", &DummyEngineType::to_JSON,
"State of the engine in JSON format",
py::arg("enclosed_in_curly_brackets") = true);
pyQDummyEngine.def("traits_get_name", &DummyEngineType::traits_get_name,
"Engine name");
pyQDummyEngine.def("traits_is_noisy", &DummyEngineType::traits_is_noisy,
"Noisy engine?");
pyQDummyEngine.def("traits_is_pure", &DummyEngineType::traits_is_pure,
"Pure state engine?");

.def("__repr__",
[](const DummyEngineType& self) {
std::ostringstream oss;
oss << self;
return oss.str();
})
.def("__copy__",
[](const DummyEngineType& self) { return DummyEngineType(self); })
.def("__deepcopy__", [](const DummyEngineType& self, py::dict) {
return DummyEngineType(self);
});
pyQDummyEngine.def("__repr__", [](const DummyEngineType& self) {
std::ostringstream oss;
oss << self;
return oss.str();
});
pyQDummyEngine.def("__copy__", [](const DummyEngineType& self) {
return DummyEngineType(self);
});
pyQDummyEngine.def("__deepcopy__",
[](const DummyEngineType& self, py::dict) {
return DummyEngineType(self);
});

if constexpr (std::is_same_v<T, ket>) {
m.def(
Expand Down
175 changes: 90 additions & 85 deletions pyqpp/include/pyqpp/classes/qengine_bind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,94 +43,99 @@ void declare_QEngineT(py::module& m) {
pyname = "_QDensityEngine";
}

py::class_<QEngineT<T>>(m, pyname.c_str())
.def(py::init<const QCircuit&>(), py::keep_alive<1, 2>())
auto pyQEngineT = py::class_<QEngineT<T>>(m, pyname.c_str());
pyQEngineT.def(py::init<const QCircuit&>(), py::keep_alive<1, 2>());

.def("execute", py::overload_cast<idx>(&QEngineT<T>::execute),
"Executes the entire quantum circuit description",
py::arg("reps") = 1)
.def(
"get_circuit",
[](const QEngineT<T>& qe) { return qe.get_circuit(); },
"Underlying quantum circuit description")
.def("get_dit", &QEngineT<T>::get_dit,
"Underlying classical dit at position i", py::arg("i"))
.def("get_dits", &QEngineT<T>::get_dits, "Underlying classical dits")
.def("get_ensure_post_selection",
&QEngineT<T>::get_ensure_post_selection,
"True if post-selection is enforced (must succeed), false "
"otherwise")
.def("get_max_post_selection_reps",
&QEngineT<T>::get_max_post_selection_reps,
"Maximum number of repetitions of a cirucit post-selection step "
"until success")
.def("get_measured_d", &QEngineT<T>::get_measured_d,
"Vector of already destructively measured qudit indexes")
.def("get_non_measured_d", &QEngineT<T>::get_non_measured_d,
"Vector of qudit indexes that were not measured destructively")
.def("get_probs", &QEngineT<T>::get_probs,
"Underlying measurement outcome probabilities")
.def("get_state", &QEngineT<T>::get_state, "Underlying quantum state")
.def(
"get_stats",
[](const QEngineT<T>& qe) {
std::map<std::string, idx> result;
const auto& stats = qe.get_stats();
for (auto&& elem : stats.data()) {
std::stringstream ss;
ss << disp(elem.first, IOManipContainerOpts{}
.set_sep("")
.set_left("")
.set_right(""));
result[ss.str()] = elem.second;
}
return result;
},
"Measurement statistics for multiple runs")
.def("post_select_ok", &QEngineT<T>::post_select_ok,
"True if post-selection was successful (or absent), false "
"otherwise")
.def("reset", &QEngineT<T>::reset, "Resets the engine",
py::arg("reset_stats") = true)
.def("reset_stats", &QEngineT<T>::reset_stats,
"Resets the collected measurement statistics hash table")
.def("set_dit", &QEngineT<T>::set_dit,
"Sets the classical dit at position i", py::arg("i"),
py::arg("value"))
.def("set_dits", &QEngineT<T>::set_dits, "Set the classical dits",
py::arg("dits"))
.def("set_ensure_post_selection",
&QEngineT<T>::set_ensure_post_selection,
"Enforces post-selection (must succeed)", py::arg("val"))
.def("set_max_post_selection_reps",
&QEngineT<T>::set_max_post_selection_reps,
py::arg("max_post_selection_reps"),
"Sets the maximum number of repetitions of a circuit "
"post-selection step until success")
.def("set_state", &QEngineT<T>::set_state,
"Sets the underlying quantum state", py::arg("state"))
.def("to_JSON", &QEngineT<T>::to_JSON,
"State of the engine in JSON format",
py::arg("enclosed_in_curly_brackets") = true)
.def("was_measured_d", &QEngineT<T>::was_measured_d,
"Whether qudit i was already measured destructively", py::arg("i"))
pyQEngineT.def("execute", py::overload_cast<idx>(&QEngineT<T>::execute),
"Executes the entire quantum circuit description",
py::arg("reps") = 1);
pyQEngineT.def(
"get_circuit", [](const QEngineT<T>& qe) { return qe.get_circuit(); },
"Underlying quantum circuit description");
pyQEngineT.def("get_dit", &QEngineT<T>::get_dit,
"Underlying classical dit at position i", py::arg("i"));
pyQEngineT.def("get_dits", &QEngineT<T>::get_dits,
"Underlying classical dits");
pyQEngineT.def("get_ensure_post_selection",
&QEngineT<T>::get_ensure_post_selection,
"True if post-selection is enforced (must succeed), false "
"otherwise");
pyQEngineT.def(
"get_max_post_selection_reps",
&QEngineT<T>::get_max_post_selection_reps,
"Maximum number of repetitions of a cirucit post-selection step "
"until success");
pyQEngineT.def("get_measured_d", &QEngineT<T>::get_measured_d,
"Vector of already destructively measured qudit indexes");
pyQEngineT.def(
"get_non_measured_d", &QEngineT<T>::get_non_measured_d,
"Vector of qudit indexes that were not measured destructively");
pyQEngineT.def("get_probs", &QEngineT<T>::get_probs,
"Underlying measurement outcome probabilities");
pyQEngineT.def("get_state", &QEngineT<T>::get_state,
"Underlying quantum state");
pyQEngineT.def(
"get_stats",
[](const QEngineT<T>& qe) {
std::map<std::string, idx> result;
const auto& stats = qe.get_stats();
for (auto&& elem : stats.data()) {
std::stringstream ss;
ss << disp(
elem.first,
IOManipContainerOpts{}.set_sep("").set_left("").set_right(
""));
result[ss.str()] = elem.second;
}
return result;
},
"Measurement statistics for multiple runs");
pyQEngineT.def("post_select_ok", &QEngineT<T>::post_select_ok,
"True if post-selection was successful (or absent), false "
"otherwise");
pyQEngineT.def("reset", &QEngineT<T>::reset, "Resets the engine",
py::arg("reset_stats") = true);
pyQEngineT.def("reset_stats", &QEngineT<T>::reset_stats,
"Resets the collected measurement statistics hash table");
pyQEngineT.def("set_dit", &QEngineT<T>::set_dit,
"Sets the classical dit at position i", py::arg("i"),
py::arg("value"));
pyQEngineT.def("set_dits", &QEngineT<T>::set_dits, "Set the classical dits",
py::arg("dits"));
pyQEngineT.def("set_ensure_post_selection",
&QEngineT<T>::set_ensure_post_selection,
"Enforces post-selection (must succeed)", py::arg("val"));
pyQEngineT.def("set_max_post_selection_reps",
&QEngineT<T>::set_max_post_selection_reps,
py::arg("max_post_selection_reps"),
"Sets the maximum number of repetitions of a circuit "
"post-selection step until success");
pyQEngineT.def("set_state", &QEngineT<T>::set_state,
"Sets the underlying quantum state", py::arg("state"));
pyQEngineT.def("to_JSON", &QEngineT<T>::to_JSON,
"State of the engine in JSON format",
py::arg("enclosed_in_curly_brackets") = true);
pyQEngineT.def("was_measured_d", &QEngineT<T>::was_measured_d,
"Whether qudit i was already measured destructively",
py::arg("i"));

.def("traits_get_name", &QEngineT<T>::traits_get_name, "Engine name")
.def("traits_is_noisy", &QEngineT<T>::traits_is_noisy, "Noisy engine?")
.def("traits_is_pure", &QEngineT<T>::traits_is_pure,
"Pure state engine?")
pyQEngineT.def("traits_get_name", &QEngineT<T>::traits_get_name,
"Engine name");
pyQEngineT.def("traits_is_noisy", &QEngineT<T>::traits_is_noisy,
"Noisy engine?");
pyQEngineT.def("traits_is_pure", &QEngineT<T>::traits_is_pure,
"Pure state engine?");

.def("__repr__",
[](const QEngineT<T>& self) {
std::ostringstream oss;
oss << self;
return oss.str();
})
.def("__copy__",
[](const QEngineT<T>& self) { return QEngineT<T>(self); })
.def("__deepcopy__", [](const QEngineT<T>& self, py::dict) {
return QEngineT<T>(self);
});
pyQEngineT.def("__repr__", [](const QEngineT<T>& self) {
std::ostringstream oss;
oss << self;
return oss.str();
});
pyQEngineT.def("__copy__",
[](const QEngineT<T>& self) { return QEngineT<T>(self); });
pyQEngineT.def("__deepcopy__", [](const QEngineT<T>& self, py::dict) {
return QEngineT<T>(self);
});

if constexpr (std::is_same_v<T, ket>) {
m.def(
Expand Down
66 changes: 36 additions & 30 deletions pyqpp/include/pyqpp/classes/qnoisy_engine_bind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,22 @@
template <typename NoiseModel, typename... CtorTypeList>
void declare_noise_model(py::module& m, const std::string& type) {
using namespace qpp;
py::class_<NoiseModel>(m, type.c_str())
.def(py::init<CtorTypeList...>())

.def("get_d", &NoiseModel::get_d, "Qudit dimension")
.def("get_Ks", &NoiseModel::get_Ks, "Vector of noise operators")
.def("get_last_idx", &NoiseModel::get_last_idx,
"Index of the last occurring noise element")
.def("get_last_K", &NoiseModel::get_last_K,
"Last occurring noise element")
.def("get_last_p", &NoiseModel::get_last_p,
"Probability of the last occurring noise element")
.def("get_probs", &NoiseModel::get_probs,
"Vector of probabilities corresponding to each noise operator");
auto pyNoiseModel = py::class_<NoiseModel>(m, type.c_str());

pyNoiseModel.def(py::init<CtorTypeList...>());

pyNoiseModel.def("get_d", &NoiseModel::get_d, "Qudit dimension");
pyNoiseModel.def("get_Ks", &NoiseModel::get_Ks,
"Vector of noise operators");
pyNoiseModel.def("get_last_idx", &NoiseModel::get_last_idx,
"Index of the last occurring noise element");
pyNoiseModel.def("get_last_K", &NoiseModel::get_last_K,
"Last occurring noise element");
pyNoiseModel.def("get_last_p", &NoiseModel::get_last_p,
"Probability of the last occurring noise element");
pyNoiseModel.def(
"get_probs", &NoiseModel::get_probs,
"Vector of probabilities corresponding to each noise operator");
}

/* qpp::QNoisyEngineT instantiator */
Expand All @@ -61,23 +64,26 @@ void declare_QNoisyEngineT(py::module& m, const std::string& type) {
} else {
pyname = "_QDensityNoisyEngine_" + type;
}
py::class_<QNoisyEngineT<T, NoiseModel>, QEngineT<T>>(m, pyname.c_str())
.def(py::init<const QCircuit&, const NoiseModel&>(),
py::keep_alive<1, 2>())

.def(
"get_noise_results",
&QNoisyEngineT<T, NoiseModel>::get_noise_results,
"Vector of noise results obtained before every step in the circuit")

.def("__copy__",
[](const QNoisyEngineT<T, NoiseModel>& self) {
return QNoisyEngineT<T, NoiseModel>(self);
})
.def("__deepcopy__",
[](const QNoisyEngineT<T, NoiseModel>& self, py::dict) {
return QNoisyEngineT<T, NoiseModel>(self);
});
auto pyQNoisyEngineT =
py::class_<QNoisyEngineT<T, NoiseModel>, QEngineT<T>>(m,
pyname.c_str());

pyQNoisyEngineT.def(py::init<const QCircuit&, const NoiseModel&>(),
py::keep_alive<1, 2>());

pyQNoisyEngineT.def(
"get_noise_results", &QNoisyEngineT<T, NoiseModel>::get_noise_results,
"Vector of noise results obtained before every step in the circuit");

pyQNoisyEngineT.def("__copy__",
[](const QNoisyEngineT<T, NoiseModel>& self) {
return QNoisyEngineT<T, NoiseModel>(self);
});
pyQNoisyEngineT.def("__deepcopy__",
[](const QNoisyEngineT<T, NoiseModel>& self, py::dict) {
return QNoisyEngineT<T, NoiseModel>(self);
});
;

if constexpr (std::is_same_v<T, ket>) {
m.def(
Expand Down
Loading

0 comments on commit 9f0ea90

Please sign in to comment.