From d5ba323bf3655802d8eba48b5cc0af9a5dc1fcea Mon Sep 17 00:00:00 2001 From: zigen Date: Thu, 10 Mar 2022 20:19:53 +0900 Subject: [PATCH 01/43] move BackendContainer impl to cc file --- quisp/modules/Backend/Backend.cc | 17 +++++++++++++++++ quisp/modules/Backend/Backend.h | 19 +++---------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/quisp/modules/Backend/Backend.cc b/quisp/modules/Backend/Backend.cc index a517e35f9..7d0f7bf43 100644 --- a/quisp/modules/Backend/Backend.cc +++ b/quisp/modules/Backend/Backend.cc @@ -3,5 +3,22 @@ namespace quisp::modules::backend { BackendContainer::BackendContainer() {} BackendContainer::~BackendContainer() {} +void BackendContainer::initialize() { + auto backend_type = std::string(par("backendType").stringValue()); + if (backend_type == "ErrorTrackingBackend") { + backend = std::make_unique(std::make_unique(this)); + } else { + throw omnetpp::cRuntimeError("Unknown backend type: %s", backend_type.c_str()); + } +} + +void BackendContainer::finish() {} + +IQuantumBackend* BackendContainer::getQuantumBackend() { + if (backend == nullptr) { + throw omnetpp::cRuntimeError("Backend is not initialized"); + } + return backend.get(); +} } // namespace quisp::modules::backend diff --git a/quisp/modules/Backend/Backend.h b/quisp/modules/Backend/Backend.h index a291229ef..dfb39ffaa 100644 --- a/quisp/modules/Backend/Backend.h +++ b/quisp/modules/Backend/Backend.h @@ -14,23 +14,10 @@ class BackendContainer : public omnetpp::cSimpleModule { BackendContainer(); ~BackendContainer(); - void initialize() override { - auto backend_type = std::string(par("backend_type").stringValue()); - if (backend_type == "ErrorTrackingBackend") { - backend = std::make_unique(std::make_unique(this)); - } else { - throw omnetpp::cRuntimeError("Unknown backend type: %s", backend_type.c_str()); - } - } + void initialize() override; + void finish() override; - void finish() override {} - - IQuantumBackend* getQuantumBackend() { - if (backend == nullptr) { - throw omnetpp::cRuntimeError("Backend is not initialized"); - } - return backend.get(); - } + IQuantumBackend* getQuantumBackend(); protected: std::unique_ptr backend; From d27957fb7a2e439319e6b3ed5dff039bcefb56d4 Mon Sep 17 00:00:00 2001 From: zigen Date: Thu, 10 Mar 2022 20:20:44 +0900 Subject: [PATCH 02/43] add QubitId for StationaryQubit --- quisp/modules/QNIC/StationaryQubit/QubitId.h | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 quisp/modules/QNIC/StationaryQubit/QubitId.h diff --git a/quisp/modules/QNIC/StationaryQubit/QubitId.h b/quisp/modules/QNIC/StationaryQubit/QubitId.h new file mode 100644 index 000000000..0cb7aef99 --- /dev/null +++ b/quisp/modules/QNIC/StationaryQubit/QubitId.h @@ -0,0 +1,33 @@ +#include "backends/Backends.h" +#include "modules/QNIC/StationaryQubit/IStationaryQubit.h" + +namespace quisp::modules::qubit_id { + +void hash_combine(std::size_t& seed, int const& v) { seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } + +class QubitId : public quisp::backends::IQubitId { + public: + QubitId(int node_addr, int qnic_index, int qnic_type, int qubit_addr) : node_addr(node_addr), qnic_index(qnic_index), qnic_type(qnic_type), qubit_addr((qubit_addr)) {} + std::size_t hash() const override { + size_t seed = std::hash()(node_addr); + hash_combine(seed, qnic_index); + hash_combine(seed, qnic_type); + hash_combine(seed, qubit_addr); + return seed; + } + + bool compare(const IQubitId& id_ref) const override { + const QubitId& id = dynamic_cast(id_ref); + return node_addr == id.node_addr && qnic_index == id.qnic_index && qnic_type == id.qnic_type && qubit_addr == id.qubit_addr; + } + + protected: + // https://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine + + int node_addr; + int qnic_index; + int qnic_type; + int qubit_addr; +}; + +} // namespace quisp::modules::qubit_id From 3a95e9952c56653969bc177401b13363acd0421b Mon Sep 17 00:00:00 2001 From: zigen Date: Fri, 11 Mar 2022 18:39:27 +0900 Subject: [PATCH 03/43] temp --- .../QNIC/StationaryQubit/StationaryQubit.cc | 96 ++++++++++--------- .../QNIC/StationaryQubit/StationaryQubit.h | 1 + 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index 503c094ec..4d99d650c 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -18,6 +18,7 @@ using namespace Eigen; using quisp::messages::PhotonicQubit; +using quisp::modules::qubit_id::QubitId; using quisp::types::CliffordOperator; using quisp::types::EigenvalueResult; using quisp::types::MeasureXResult; @@ -40,59 +41,58 @@ StationaryQubit::StationaryQubit() : provider(utils::ComponentProvider{this}) {} void StationaryQubit::initialize() { // read and set parameters emission_success_probability = par("emission_success_probability"); - memory_err.X_error_rate = (double)par("memory_x_error_rate").doubleValue(); - memory_err.Y_error_rate = (double)par("memory_y_error_rate").doubleValue(); - memory_err.Z_error_rate = (double)par("memory_z_error_rate").doubleValue(); - memory_err.excitation_error_rate = (double)par("memory_energy_excitation_rate").doubleValue(); - memory_err.relaxation_error_rate = (double)par("memory_energy_relaxation_rate").doubleValue(); - memory_err.completely_mixed_rate = (double)par("memory_completely_mixed_rate").doubleValue(); - memory_err.error_rate = memory_err.X_error_rate + memory_err.Y_error_rate + memory_err.Z_error_rate + memory_err.excitation_error_rate + memory_err.relaxation_error_rate + - memory_err.completely_mixed_rate; // This is per μs. + // memory_err.X_error_rate = (double)par("memory_X_error_rate").doubleValue(); + // memory_err.Y_error_rate = (double)par("memory_Y_error_rate").doubleValue(); + // memory_err.Z_error_rate = (double)par("memory_Z_error_rate").doubleValue(); + // memory_err.excitation_error_rate = (double)par("memory_energy_excitation_rate").doubleValue(); + // memory_err.relaxation_error_rate = (double)par("memory_energy_relaxation_rate").doubleValue(); + // memory_err.completely_mixed_rate = (double)par("memory_completely_mixed_rate").doubleValue(); + // memory_err.error_rate = memory_err.X_error_rate + memory_err.Y_error_rate + memory_err.Z_error_rate + memory_err.excitation_error_rate + memory_err.relaxation_error_rate + + // memory_err.completely_mixed_rate; // This is per μs. Memory_Transition_matrix = MatrixXd::Zero(7, 7); // clang-format off - Memory_Transition_matrix << - 1 - memory_err.error_rate, memory_err.X_error_rate, memory_err.Z_error_rate, memory_err.Y_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - memory_err.X_error_rate, 1 - memory_err.error_rate, memory_err.Y_error_rate, memory_err.Z_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - memory_err.Z_error_rate, memory_err.Y_error_rate, 1 - memory_err.error_rate, memory_err.X_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - memory_err.Y_error_rate, memory_err.Z_error_rate, memory_err.X_error_rate, 1 - memory_err.error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - 0, 0, 0, 0, 1 - memory_err.relaxation_error_rate - memory_err.completely_mixed_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - 0, 0, 0, 0, memory_err.excitation_error_rate, 1 - memory_err.excitation_error_rate - memory_err.completely_mixed_rate, memory_err.completely_mixed_rate, - 0, 0, 0, 0, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, 1 - memory_err.excitation_error_rate - memory_err.relaxation_error_rate; + // Memory_Transition_matrix << + // 1 - memory_err.error_rate, memory_err.X_error_rate, memory_err.Z_error_rate, memory_err.Y_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, + // memory_err.X_error_rate, 1 - memory_err.error_rate, memory_err.Y_error_rate, memory_err.Z_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, + // memory_err.Z_error_rate, memory_err.Y_error_rate, 1 - memory_err.error_rate, memory_err.X_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, + // memory_err.Y_error_rate, memory_err.Z_error_rate, memory_err.X_error_rate, 1 - memory_err.error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, + // 0, 0, 0, 0, 1 - memory_err.relaxation_error_rate - memory_err.completely_mixed_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, + // 0, 0, 0, 0, memory_err.excitation_error_rate, 1 - memory_err.excitation_error_rate - memory_err.completely_mixed_rate, memory_err.completely_mixed_rate, + // 0, 0, 0, 0, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, 1 - memory_err.excitation_error_rate - memory_err.relaxation_error_rate; // clang-format on - god_err.has_x_error = false; - god_err.has_z_error = false; - god_err.has_excitation_error = false; - god_err.has_relaxation_error = false; - god_err.has_completely_mixed_error = false; - setSingleQubitGateErrorModel(Hgate_error, "h_gate"); - setSingleQubitGateErrorModel(Xgate_error, "x_gate"); - setSingleQubitGateErrorModel(Zgate_error, "z_gate"); - setTwoQubitGateErrorCeilings(CNOTgate_error, "cnot_gate"); - setMeasurementErrorModel(Measurement_error); + // std::cout << "Memory_Transition_matrix = \n " << Memory_Transition_matrix << " done \n"; + + // setSingleQubitGateErrorModel(Hgate_error, "Hgate"); + // setSingleQubitGateErrorModel(Xgate_error, "Xgate"); + // setSingleQubitGateErrorModel(Zgate_error, "Zgate"); + // setTwoQubitGateErrorCeilings(CNOTgate_error, "CNOTgate"); + // setMeasurementErrorModel(Measurement_error); + + // std::cout << Memory_Transition_matrix << "\n"; // Set error matrices. This is used in the process of simulating tomography. - Pauli.X << 0, 1, 1, 0; - Pauli.Y << 0, Complex(0, -1), Complex(0, 1), 0; - Pauli.Z << 1, 0, 0, -1; - Pauli.I << 1, 0, 0, 1; + // Pauli.X << 0, 1, 1, 0; + // Pauli.Y << 0, Complex(0, -1), Complex(0, 1), 0; + // Pauli.Z << 1, 0, 0, -1; + // Pauli.I << 1, 0, 0, 1; // Set measurement operators. This is used in the process of simulating tomography. - meas_op.X_basis.plus << 0.5, 0.5, 0.5, 0.5; - meas_op.X_basis.minus << 0.5, -0.5, -0.5, 0.5; - meas_op.X_basis.plus_ket << 1 / sqrt(2), 1 / sqrt(2); - meas_op.X_basis.minus_ket << 1 / sqrt(2), -1 / sqrt(2); - meas_op.X_basis.basis = 'X'; - meas_op.Z_basis.plus << 1, 0, 0, 0; - meas_op.Z_basis.minus << 0, 0, 0, 1; - meas_op.Z_basis.plus_ket << 1, 0; - meas_op.Z_basis.minus_ket << 0, 1; - meas_op.Z_basis.basis = 'Z'; - meas_op.Y_basis.plus << 0.5, Complex(0, -0.5), Complex(0, 0.5), 0.5; - meas_op.Y_basis.minus << 0.5, Complex(0, 0.5), Complex(0, -0.5), 0.5; - meas_op.Y_basis.plus_ket << 1 / sqrt(2), Complex(0, 1 / sqrt(2)); - meas_op.Y_basis.minus_ket << 1 / sqrt(2), -Complex(0, 1 / sqrt(2)); - meas_op.Y_basis.basis = 'Y'; - meas_op.identity << 1, 0, 0, 1; + // meas_op.X_basis.plus << 0.5, 0.5, 0.5, 0.5; + // meas_op.X_basis.minus << 0.5, -0.5, -0.5, 0.5; + // meas_op.X_basis.plus_ket << 1 / sqrt(2), 1 / sqrt(2); + // meas_op.X_basis.minus_ket << 1 / sqrt(2), -1 / sqrt(2); + // meas_op.X_basis.basis = 'X'; + // meas_op.Z_basis.plus << 1, 0, 0, 0; + // meas_op.Z_basis.minus << 0, 0, 0, 1; + // meas_op.Z_basis.plus_ket << 1, 0; + // meas_op.Z_basis.minus_ket << 0, 1; + // meas_op.Z_basis.basis = 'Z'; + // meas_op.Y_basis.plus << 0.5, Complex(0, -0.5), Complex(0, 0.5), 0.5; + // meas_op.Y_basis.minus << 0.5, Complex(0, 0.5), Complex(0, -0.5), 0.5; + // meas_op.Y_basis.plus_ket << 1 / sqrt(2), Complex(0, 1 / sqrt(2)); + // meas_op.Y_basis.minus_ket << 1 / sqrt(2), -Complex(0, 1 / sqrt(2)); + // meas_op.Y_basis.basis = 'Y'; + // meas_op.identity << 1, 0, 0, 1; // Get parameters from omnet stationary_qubit_address = par("stationary_qubit_address"); @@ -109,7 +109,7 @@ void StationaryQubit::initialize() { vertex_operator = CliffordOperator::H; auto *backend = provider.getQuantumBackend(); - // qubit_ref = backend->getQubit({node_address, qnic_index, qnic_type, stationary_qubit_address}); + qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationary_qubit_address)); // watch variables to show them in the GUI WATCH(emitted_time); @@ -364,6 +364,8 @@ void StationaryQubit::setBusy() { // Re-initialization of this stationary qubit // This is called at the beginning of the simulation (in initialization() above), and whenever it is reinitialized via the RealTimeController. void StationaryQubit::setFree(bool consumed) { + qubit_ref->setFree(); + /********************************/ num_purified = 0; locked = false; locked_ruleset_id = -1; diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index b7c31e2f4..90aa7ce8e 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -11,6 +11,7 @@ #include #include #include "IStationaryQubit.h" +#include "QubitId.h" namespace quisp { namespace modules { From 654c6510b174cea06b3aed98cda230b6357f6da4 Mon Sep 17 00:00:00 2001 From: zigen Date: Tue, 22 Mar 2022 15:48:18 +0900 Subject: [PATCH 04/43] move measure_density_independent to EtQubit and delete god error state in types for ErrorTracking backend --- quisp/backends/ErrorTracking/Qubit.cc | 218 +++++++++++++++++- quisp/backends/ErrorTracking/Qubit.h | 21 +- .../ErrorTracking/Qubit_memory_error_test.cc | 74 ++++++ quisp/backends/ErrorTracking/test.h | 3 + quisp/backends/ErrorTracking/types.h | 15 +- quisp/backends/interfaces/IQubit.h | 48 ++-- 6 files changed, 344 insertions(+), 35 deletions(-) diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index bd71c9e9f..81f149d19 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -255,8 +255,8 @@ void ErrorTrackingQubit::setRelaxedDensityMatrix() { has_relaxation_error = true; has_x_error = false; has_z_error = false; - // GOD_dm_Xerror = false; - // GOD_dm_Zerror = false; + god_dm_has_x_error = false; + god_dm_has_z_error = false; // Still entangled if (entangled_partner != nullptr) { @@ -271,8 +271,8 @@ void ErrorTrackingQubit::setExcitedDensityMatrix() { has_relaxation_error = false; has_x_error = false; has_z_error = false; - // GOD_dm_Xerror = false; - // GOD_dm_Zerror = false; + god_dm_has_x_error = false; + god_dm_has_z_error = false; if (entangled_partner != nullptr) { // If it used to be entangled... entangled_partner->updated_time = backend->getSimTime(); @@ -414,6 +414,216 @@ bool ErrorTrackingQubit::purifyZ(IQubit* const target_qubit) { return this->correlationMeasureZ() == MeasureZResult::NO_X_ERROR; } +Matrix2cd ErrorTrackingQubit::getErrorMatrix() { + if (has_completely_mixed_error || has_relaxation_error) { + throw std::runtime_error("CMerror in getErrorMatrix. Not supposed to happen."); + } + if (has_z_error && has_x_error) return pauli.Y; + if (has_z_error) return pauli.Z; + if (has_x_error) return pauli.X; + return pauli.I; +} + +// returns the density matrix of the Bell pair with error. This assumes that this is entangled with another stationary qubit. +// Measurement output will be based on this matrix, as long as it is still entangled. +QuantumState ErrorTrackingQubit::getQuantumState() { + if (has_excitation_error || has_relaxation_error) throw std::runtime_error("this qubit is excited or relaxed"); + if (entangled_partner == nullptr) throw std::runtime_error("no entangled partner"); + if (entangled_partner->has_excitation_error || entangled_partner->has_relaxation_error) throw std::runtime_error("partner qubit is excited or relaxed"); + + Matrix4cd error_mat = kroneckerProduct(getErrorMatrix(), entangled_partner->getErrorMatrix()).eval(); + // Assumes that the state is a 2 qubit state |00> + |11> + Vector4cd ideal_bell_state(1 / sqrt(2), 0, 0, 1 / sqrt(2)); + Vector4cd actual_bell_state = error_mat * ideal_bell_state; + + QuantumState q; + q.state_in_density_matrix = actual_bell_state * actual_bell_state.adjoint(); + q.state_in_ket = actual_bell_state; + return q; +} + +MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { + if (this->entangled_partner == nullptr && density_matrix_collapsed(0, 0).real() == -111) { + std::cout << density_matrix_collapsed << "\n"; + throw std::runtime_error("Measuring a qubit that is not entangled with another qubit. Probably not what you want! Check whether address for each node is unique!!!"); + } + MeasurementOperator this_measurement = randomMeasurementBasisSelection(); // Select basis randomly + char Output; + bool Output_is_plus; + + // Add memory error depending on the idle time. If excited/relaxed, this will immediately break entanglement, leaving the other qubit as completely mixed. + applyMemoryError(); + + // This becomes nullptr if this qubit got excited/relaxed or measured. + if (this->entangled_partner != nullptr) { + if (this->entangled_partner->entangled_partner == nullptr) { + throw std::runtime_error("invalid entanglement partner"); + } + // if (partner_measured) error("Entangled partner not nullptr but partner already measured....? Probably wrong."); + if (has_completely_mixed_error || has_excitation_error || has_relaxation_error) { + std::cout << "[Error]" << this << "\n"; + throw std::runtime_error("Entangled but completely mixed / Excited / Relaxed ? Probably wrong."); + } + // Also do the same on the partner if it is still entangled! This could break the entanglement due to relaxation/excitation error! + entangled_partner->applyMemoryError(); + } + + /*-For debugging-*/ + char GOD_state = 'F'; // Completely mixed + + if (has_excitation_error) + GOD_state = 'E'; + else if (has_excitation_error /* XXX: this might be relaxation error? */) + GOD_state = 'R'; + else if (has_completely_mixed_error) + GOD_state = 'C'; + else if (!has_x_error && has_z_error) // To check stabilizers.... + GOD_state = 'Z'; + else if (has_x_error && !has_z_error) + GOD_state = 'X'; + else if (has_x_error && has_z_error) + GOD_state = 'Y'; + + /*---------------*/ + + // if there is an entanglement + if (this->entangled_partner != nullptr) { + // This qubit is nullptr + if (this->entangled_partner->entangled_partner == nullptr) { + throw std::runtime_error("Entangled_partner track wrong\n"); + } + } + + // if the partner qubit is measured, + if (this->partner_measured || has_completely_mixed_error || has_excitation_error || + has_relaxation_error) { // The case when the density matrix is completely local to this qubit. + + if (density_matrix_collapsed(0, 0).real() == -111) { // We always need some kind of density matrix inside this if statement. + throw std::runtime_error("Single qubit density matrix not stored properly after partner's measurement, excitation/relaxation error."); + } + bool Xerr = has_x_error; + bool Zerr = has_z_error; + // This qubit's density matrix was created when the partner measured his own. + // Because this qubit can be measured after that, we need to update the stored density matrix according to new errors occurred due to memory error. + + if (Xerr != god_dm_has_x_error) { // Another X error to the dm. + density_matrix_collapsed = pauli.X * density_matrix_collapsed * pauli.X.adjoint(); + } + if (Zerr != god_dm_has_z_error) { // Another Z error to the dm. + density_matrix_collapsed = pauli.Z * density_matrix_collapsed * pauli.Z.adjoint(); + } + + // std::cout<<"Not entangled anymore. Density matrix is "<dblrand(); + if (dbl < Prob_plus.real()) { + Output = '+'; + Output_is_plus = true; + } else { + Output = '-'; + Output_is_plus = false; + } + // std::cout<<"\n This qubit was "<partner_measured && !has_completely_mixed_error && !(has_relaxation_error || has_excitation_error) && this->entangled_partner != nullptr) { + // This is assuming that this is some other qubit is entangled. Only Pauli errors are assumed. + QuantumState current_state = getQuantumState(); + std::cout << "Current entangled state is " << current_state.state_in_ket << "\n"; + + bool Xerr = god_dm_has_x_error; + bool Zerr = god_dm_has_z_error; + // std::cout<<"Entangled state is "<dblrand(); + + Vector2cd ms; + if (dbl < Prob_plus.real()) { // Measurement output was plus + Output = '+'; + ms = this_measurement.plus_ket; + Output_is_plus = true; + } else { // Otherwise, it was negative. + Output = '-'; + ms = this_measurement.minus_ket; + Output_is_plus = false; + } + // Now we have to calculate the density matrix of a single qubit that used to be entangled with this. + Matrix2cd partners_dm, normalized_partners_dm; + partners_dm = kroneckerProduct(ms.adjoint(), measurement_op.identity).eval() * current_state.state_in_density_matrix * + kroneckerProduct(ms.adjoint(), measurement_op.identity).eval().adjoint(); + normalized_partners_dm = partners_dm / partners_dm.trace(); + std::cout << "kroneckerProduct(ms.adjoint(),meas_op.identity).eval() = " << kroneckerProduct(ms.adjoint(), measurement_op.identity).eval() << "\n"; + std::cout << "dm = " << current_state.state_in_density_matrix << "\n"; + std::cout << "State was " << kroneckerProduct(ms.adjoint(), measurement_op.identity).eval() * current_state.state_in_density_matrix << "\n"; + std::cout << "\n This qubit was " << this_measurement.basis << "(" << Output << "). Partner's dm is now = " << normalized_partners_dm << "\n"; + entangled_partner->density_matrix_collapsed = normalized_partners_dm; + + // We actually do not need this as long as deleting entangled_partner completely is totally fine. + entangled_partner->partner_measured = true; + // if(entangled_partner->getIndex() == 71 && entangled_partner->node_address == 3) + // std::cout<<"-------------------"<node_address<<"] overwritten dm.\n"; + + // Break entanglement. + entangled_partner->entangled_partner = nullptr; + // Save what error it had, when this density matrix was calculated. + // Error may get updated in the future, so we need to track what error has been considered already in the dm. + entangled_partner->god_dm_has_x_error = entangled_partner->has_x_error; + entangled_partner->god_dm_has_z_error = entangled_partner->has_z_error; + } else { + throw std::runtime_error("Check condition in measure func."); + } + + // add measurement error + auto rand_num = backend->dblrand(); + if (this_measurement.basis == measurement_op.x_basis.basis && rand_num < measurement_err.x_error_rate || + this_measurement.basis == measurement_op.y_basis.basis && rand_num < measurement_err.y_error_rate || + this_measurement.basis == measurement_op.z_basis.basis && rand_num < measurement_err.z_error_rate) { + Output_is_plus = !Output_is_plus; + } + + MeasurementOutcome o; + o.basis = this_measurement.basis; + o.outcome_is_plus = Output_is_plus; + o.GOD_clean = GOD_state; + return o; +} + +MeasurementOperator ErrorTrackingQubit::randomMeasurementBasisSelection() { + MeasurementOperator this_measurement; + double dbl = backend->dblrand(); // Random double value for random basis selection. + std::cout << "Random dbl = " << dbl << "! \n "; + + if (dbl < ((double)1 / (double)3)) { // X measurement! + std::cout << "X measurement\n"; + this_measurement.plus = measurement_op.x_basis.plus; + this_measurement.minus = measurement_op.x_basis.minus; + this_measurement.basis = measurement_op.x_basis.basis; + this_measurement.plus_ket = measurement_op.x_basis.plus_ket; + this_measurement.minus_ket = measurement_op.x_basis.minus_ket; + } else if (dbl >= ((double)1 / (double)3) && dbl < ((double)2 / (double)3)) { + std::cout << "Z measurement\n"; + this_measurement.plus = measurement_op.z_basis.plus; + this_measurement.minus = measurement_op.z_basis.minus; + this_measurement.basis = measurement_op.z_basis.basis; + this_measurement.plus_ket = measurement_op.z_basis.plus_ket; + this_measurement.minus_ket = measurement_op.z_basis.minus_ket; + } else { + std::cout << "Y measurement\n"; + this_measurement.plus = measurement_op.y_basis.plus; + this_measurement.minus = measurement_op.y_basis.minus; + this_measurement.basis = measurement_op.y_basis.basis; + this_measurement.plus_ket = measurement_op.y_basis.plus_ket; + this_measurement.minus_ket = measurement_op.y_basis.minus_ket; + } + return this_measurement; +} + // Set error matrices. This is used in the process of simulating tomography. const SingleQubitErrorModel ErrorTrackingQubit::pauli = {.X = (Matrix2cd() << 0, 1, 1, 0).finished(), .Y = (Matrix2cd() << 0, Complex(0, -1), Complex(0, 1), 0).finished(), diff --git a/quisp/backends/ErrorTracking/Qubit.h b/quisp/backends/ErrorTracking/Qubit.h index c697cee67..063ac85bd 100644 --- a/quisp/backends/ErrorTracking/Qubit.h +++ b/quisp/backends/ErrorTracking/Qubit.h @@ -15,15 +15,18 @@ using abstract::EigenvalueResult; using abstract::IQuantumBackend; using abstract::IQubit; using abstract::IQubitId; +using abstract::MeasurementOutcome; using abstract::MeasureXResult; using abstract::MeasureYResult; using abstract::MeasureZResult; using abstract::SimTime; using abstract::SimTimeUnit; using Eigen::Matrix2cd; +using Eigen::Matrix4cd; using Eigen::MatrixPower; using Eigen::MatrixXd; using Eigen::Vector2cd; +using Eigen::Vector4cd; class ErrorTrackingBackend; class ErrorTrackingQubit : public IQubit { @@ -36,17 +39,18 @@ class ErrorTrackingQubit : public IQubit { void reset(); void setFree() override; - MeasureXResult correlationMeasureX(); - MeasureYResult correlationMeasureY(); - MeasureZResult correlationMeasureZ(); - EigenvalueResult localMeasureX(); - EigenvalueResult localMeasureZ(); + MeasureXResult correlationMeasureX() override; + MeasureYResult correlationMeasureY() override; + MeasureZResult correlationMeasureZ() override; + EigenvalueResult localMeasureX() override; + EigenvalueResult localMeasureZ() override; void gateX() override; void gateZ() override; void gateH() override; void gateCNOT(IQubit* const control_qubit) override; bool purifyX(IQubit* const control_qubit) override; bool purifyZ(IQubit* const target_qubit) override; + MeasurementOutcome measureDensityIndependent() override; protected: void applySingleQubitGateError(SingleGateErrorModel const& err); @@ -57,7 +61,9 @@ class ErrorTrackingQubit : public IQubit { void setRelaxedDensityMatrix(); void setExcitedDensityMatrix(); void setCompletelyMixedDensityMatrix(); - + Matrix2cd getErrorMatrix(); + QuantumState getQuantumState(); + MeasurementOperator randomMeasurementBasisSelection(); void update(); // constants @@ -73,11 +79,14 @@ class ErrorTrackingQubit : public IQubit { static const MeasurementOperators measurement_op; // state + bool god_dm_has_x_error = false; + bool god_dm_has_z_error = false; bool has_x_error = false; bool has_z_error = false; bool has_relaxation_error = false; bool has_excitation_error = false; bool has_completely_mixed_error = false; + bool partner_measured = false; SimTime updated_time = SimTime(0); Matrix2cd density_matrix_collapsed; // Used when partner has been measured. bool no_density_matrix_nullptr_entangled_partner_ok = false; diff --git a/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc b/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc index f6fcb8848..7ec971692 100644 --- a/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc @@ -1,11 +1,17 @@ #include #include #include +#include #include +#include "backends/ErrorTracking/types.h" #include "test.h" namespace { using namespace quisp_test::backends; +using Eigen::Matrix2cd; +using Eigen::Matrix4cd; +using Eigen::Vector4cd; +using quisp::backends::error_tracking::QuantumState; class ETQubitMemoryErrorTest : public ::testing::Test { protected: @@ -16,6 +22,7 @@ class ETQubitMemoryErrorTest : public ::testing::Test { rng->double_value = .0; backend = std::make_unique(std::unique_ptr(rng)); qubit = dynamic_cast(backend->getQubit(0)); + partner_qubit = dynamic_cast(backend->getQubit(1)); if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); backend->setSimTime(SimTime(1, SIMTIME_US)); fillParams(qubit); @@ -34,6 +41,7 @@ class ETQubitMemoryErrorTest : public ::testing::Test { } Qubit* qubit; + Qubit* partner_qubit; std::unique_ptr backend; TestRNG* rng; }; @@ -392,4 +400,70 @@ TEST_F(ETQubitMemoryErrorTest, apply_memory_error_relaxation_error) { EXPECT_FALSE(qubit->has_completely_mixed_error); } +TEST_F(ETQubitMemoryErrorTest, getErrorMatrixTest) { + Matrix2cd err; + + err = qubit->getErrorMatrix(); + EXPECT_EQ(Matrix2cd::Identity(), err); + + Matrix2cd Z(2, 2); + Z << 1, 0, 0, -1; + qubit->addErrorZ(); + err = qubit->getErrorMatrix(); + EXPECT_EQ(Z, err); + qubit->setFree(); + + Matrix2cd X(2, 2); + X << 0, 1, 1, 0; + qubit->addErrorX(); + err = qubit->getErrorMatrix(); + EXPECT_EQ(X, err); + qubit->setFree(); + + Matrix2cd Y(2, 2); + Y << 0, Complex(0, -1), Complex(0, 1), 0; + qubit->addErrorX(); + qubit->addErrorZ(); + err = qubit->getErrorMatrix(); + EXPECT_EQ(Y, err); + qubit->setFree(); +} + +TEST_F(ETQubitMemoryErrorTest, getQuantumState) { + qubit->entangled_partner = partner_qubit; + + QuantumState state; + + state = qubit->getQuantumState(); + Vector4cd state_vector(4); + state_vector << 1 / sqrt(2), 0, 0, 1 / sqrt(2); + Matrix4cd dm(4, 4); + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); + + qubit->addErrorX(); + state = qubit->getQuantumState(); + state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); + qubit->addErrorX(); + + partner_qubit->addErrorX(); + state = qubit->getQuantumState(); + state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); + partner_qubit->addErrorX(); + + qubit->addErrorZ(); + state = qubit->getQuantumState(); + state_vector << 1 / sqrt(2), 0, 0, -1 / sqrt(2); + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); + qubit->addErrorZ(); +} } // namespace diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index a10479ae5..7b6e9f796 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -51,6 +51,8 @@ class Qubit : public ErrorTrackingQubit { using ErrorTrackingQubit::gate_err_h; using ErrorTrackingQubit::gate_err_x; using ErrorTrackingQubit::gate_err_z; + using ErrorTrackingQubit::getErrorMatrix; + using ErrorTrackingQubit::getQuantumState; using ErrorTrackingQubit::has_completely_mixed_error; using ErrorTrackingQubit::has_excitation_error; using ErrorTrackingQubit::has_relaxation_error; @@ -58,6 +60,7 @@ class Qubit : public ErrorTrackingQubit { using ErrorTrackingQubit::has_z_error; using ErrorTrackingQubit::localMeasureX; using ErrorTrackingQubit::localMeasureZ; + using ErrorTrackingQubit::measureDensityIndependent; using ErrorTrackingQubit::measurement_err; using ErrorTrackingQubit::setMemoryErrorRates; using ErrorTrackingQubit::updated_time; diff --git a/quisp/backends/ErrorTracking/types.h b/quisp/backends/ErrorTracking/types.h index 40b209017..337f1163a 100644 --- a/quisp/backends/ErrorTracking/types.h +++ b/quisp/backends/ErrorTracking/types.h @@ -1,4 +1,4 @@ -#include +#pragma once #include #include @@ -140,14 +140,6 @@ struct MeasurementErrorModel { } }; -struct GodErrorState { - bool has_x_error; - bool has_z_error; - bool has_excitation_error; - bool has_relaxation_error; - bool has_completely_mixed_error; -}; - // Matrices of single qubit errors. Used when conducting tomography. struct SingleQubitErrorModel { Eigen::Matrix2cd X; // double 2*2 matrix @@ -172,4 +164,9 @@ struct MeasurementOperators { Eigen::Matrix2cd identity; }; +struct QuantumState { + Eigen::Matrix4cd state_in_density_matrix; + Eigen::Vector4cd state_in_ket; +}; + } // namespace quisp::backends::error_tracking diff --git a/quisp/backends/interfaces/IQubit.h b/quisp/backends/interfaces/IQubit.h index c512bef8d..488d89c4d 100644 --- a/quisp/backends/interfaces/IQubit.h +++ b/quisp/backends/interfaces/IQubit.h @@ -1,5 +1,29 @@ +#pragma once #include namespace quisp::backends::abstract { + +enum class MeasureXResult : int { + NO_Z_ERROR, + HAS_Z_ERROR, +}; +enum class MeasureYResult : int { + NO_XZ_ERROR, + HAS_XZ_ERROR, +}; +enum class MeasureZResult : int { + NO_X_ERROR, + HAS_X_ERROR, +}; +enum class EigenvalueResult : int { + PLUS_ONE, + MINUS_ONE, +}; +struct MeasurementOutcome { + char basis; + bool outcome_is_plus; + char GOD_clean; +}; + class IQubit { public: IQubit(){}; @@ -20,22 +44,14 @@ class IQubit { virtual void gateCZ(IQubit *const control_qubit) { throw std::runtime_error("gateCZ not implemented"); }; virtual bool purifyX(IQubit *const control_qubit) { throw std::runtime_error("gateCZ not implemented"); }; virtual bool purifyZ(IQubit *const target_qubit) { throw std::runtime_error("gateCZ not implemented"); }; -}; -enum class MeasureXResult : int { - NO_Z_ERROR, - HAS_Z_ERROR, -}; -enum class MeasureYResult : int { - NO_XZ_ERROR, - HAS_XZ_ERROR, -}; -enum class MeasureZResult : int { - NO_X_ERROR, - HAS_X_ERROR, -}; -enum class EigenvalueResult : int { - PLUS_ONE, - MINUS_ONE, + // measurements + virtual MeasureXResult correlationMeasureX() { throw std::runtime_error("correlationMeasureX not implemented"); } + virtual MeasureYResult correlationMeasureY() { throw std::runtime_error("correlationMeasureY not implemented"); } + virtual MeasureZResult correlationMeasureZ() { throw std::runtime_error("correlationMeasureZ not implemented"); } + virtual EigenvalueResult localMeasureX() { throw std::runtime_error("localMeasureX not implemented"); } + virtual EigenvalueResult localMeasureZ() { throw std::runtime_error("localMeasureZ not implemented"); } + virtual MeasurementOutcome measureDensityIndependent() { throw std::runtime_error("measureDensityIndependent not implemented"); } }; + } // namespace quisp::backends::abstract From 7eec57c0f16086b14153b80cefd34548b3130e06 Mon Sep 17 00:00:00 2001 From: zigen Date: Tue, 22 Mar 2022 15:48:40 +0900 Subject: [PATCH 05/43] fix hash_combine in QubitId --- quisp/modules/QNIC/StationaryQubit/QubitId.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/quisp/modules/QNIC/StationaryQubit/QubitId.h b/quisp/modules/QNIC/StationaryQubit/QubitId.h index 0cb7aef99..9780231d0 100644 --- a/quisp/modules/QNIC/StationaryQubit/QubitId.h +++ b/quisp/modules/QNIC/StationaryQubit/QubitId.h @@ -1,18 +1,17 @@ +#pragma once #include "backends/Backends.h" #include "modules/QNIC/StationaryQubit/IStationaryQubit.h" namespace quisp::modules::qubit_id { -void hash_combine(std::size_t& seed, int const& v) { seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } - class QubitId : public quisp::backends::IQubitId { public: QubitId(int node_addr, int qnic_index, int qnic_type, int qubit_addr) : node_addr(node_addr), qnic_index(qnic_index), qnic_type(qnic_type), qubit_addr((qubit_addr)) {} std::size_t hash() const override { size_t seed = std::hash()(node_addr); - hash_combine(seed, qnic_index); - hash_combine(seed, qnic_type); - hash_combine(seed, qubit_addr); + hashCombine(seed, qnic_index); + hashCombine(seed, qnic_type); + hashCombine(seed, qubit_addr); return seed; } @@ -23,6 +22,7 @@ class QubitId : public quisp::backends::IQubitId { protected: // https://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine + void hashCombine(std::size_t& seed, int const& v) const { seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } int node_addr; int qnic_index; From 70cb6efcb5d99db768e0e30af439125c3881495b Mon Sep 17 00:00:00 2001 From: zigen Date: Tue, 22 Mar 2022 15:50:37 +0900 Subject: [PATCH 06/43] connect StationaryQubit to its backend --- quisp/backends/Backends.h | 6 + .../QNIC/StationaryQubit/IStationaryQubit.h | 56 +- .../QNIC/StationaryQubit/StationaryQubit.cc | 789 +---------- .../QNIC/StationaryQubit/StationaryQubit.h | 26 +- .../StationaryQubit_gate_error_test.cc | 1158 +++++++++-------- .../StationaryQubit_measurement_test.cc | 1024 +++++++-------- .../StationaryQubit_memory_error_test.cc | 533 ++++---- .../StationaryQubit/StationaryQubit_test.cc | 392 +++--- quisp/test_utils/mock_modules/MockQubit.h | 9 +- 9 files changed, 1620 insertions(+), 2373 deletions(-) diff --git a/quisp/backends/Backends.h b/quisp/backends/Backends.h index 7de7b5bf2..f4f098a94 100644 --- a/quisp/backends/Backends.h +++ b/quisp/backends/Backends.h @@ -1,14 +1,20 @@ #pragma once #include "ErrorTracking/Backend.h" +#include "backends/interfaces/IQubit.h" #include "interfaces/IQuantumBackend.h" #include "interfaces/IQubitId.h" // the namespace for exposing the backend namespace quisp::backends { +using abstract::EigenvalueResult; using abstract::IQuantumBackend; using abstract::IQubit; using abstract::IQubitId; +using abstract::MeasurementOutcome; +using abstract::MeasureXResult; +using abstract::MeasureYResult; +using abstract::MeasureZResult; using error_tracking::ErrorTrackingBackend; using error_tracking::ErrorTrackingQubit; diff --git a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h index c885b284b..f7ac6ebe9 100644 --- a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h @@ -1,28 +1,18 @@ #pragma once #include +#include #include #include + namespace quisp { namespace types { -enum class MeasureXResult : int { - NO_Z_ERROR, - HAS_Z_ERROR, -}; -enum class MeasureYResult : int { - NO_XZ_ERROR, - HAS_XZ_ERROR, -}; -enum class MeasureZResult : int { - NO_X_ERROR, - HAS_X_ERROR, -}; - -enum class EigenvalueResult : int { - PLUS_ONE, - MINUS_ONE, -}; +using quisp::backends::EigenvalueResult; +using quisp::backends::MeasurementOutcome; +using quisp::backends::MeasureXResult; +using quisp::backends::MeasureYResult; +using quisp::backends::MeasureZResult; enum class CliffordOperator : int { Id = 0, @@ -176,6 +166,7 @@ class IStationaryQubit : public omnetpp::cSimpleModule { IStationaryQubit(){}; virtual ~IStationaryQubit(){}; + // RTC virtual void setFree(bool consumed) = 0; /*In use. E.g. waiting for purification result.*/ virtual void Lock(unsigned long rs_id, int rule_id, int action_id) = 0; @@ -198,18 +189,10 @@ class IStationaryQubit : public omnetpp::cSimpleModule { /** * Performs measurement and returns +(true) or -(false) based on the density matrix of the state. Used for tomography. * */ - virtual measurement_outcome measure_density_independent() = 0; /*Separate dm calculation*/ - virtual types::EigenvalueResult measureX() = 0; - virtual types::EigenvalueResult measureY() = 0; - virtual types::EigenvalueResult measureZ() = 0; - - virtual void CNOT_gate(IStationaryQubit *control_qubit) = 0; - virtual void Hadamard_gate() = 0; - virtual void Z_gate() = 0; - virtual void X_gate() = 0; - virtual bool Xpurify(IStationaryQubit *resource_qubit) = 0; - virtual bool Zpurify(IStationaryQubit *resource_qubit) = 0; + // RandomMeasureAction + virtual types::MeasurementOutcome measure_density_independent() = 0; /*Separate dm calculation*/ + // graph internal virtual void cnotGate(IStationaryQubit *control_qubit) = 0; virtual void hadamardGate() = 0; virtual void zGate() = 0; @@ -219,12 +202,20 @@ class IStationaryQubit : public omnetpp::cSimpleModule { virtual void excite() = 0; virtual void relax() = 0; + // SwappingAction, SimultaneousSwappingAction + virtual void CNOT_gate(IStationaryQubit *control_qubit) = 0; + // SimultaneousSwappingAction + virtual void Hadamard_gate() = 0; + // RTC + virtual void Z_gate() = 0; + virtual void X_gate() = 0; + // Action + virtual bool Xpurify(IStationaryQubit *resource_qubit) = 0; + virtual bool Zpurify(IStationaryQubit *resource_qubit) = 0; + /*GOD parameters*/ - GodErrorState god_err; + // SwappingAction virtual void setEntangledPartnerInfo(IStationaryQubit *partner) = 0; - virtual void setCompletelyMixedDensityMatrix() = 0; - virtual void addXerror() = 0; - virtual void addZerror() = 0; int stationary_qubit_address; int node_address; @@ -243,6 +234,7 @@ class IStationaryQubit : public omnetpp::cSimpleModule { IStationaryQubit *entangled_partner = nullptr; /** Photon emitted at*/ omnetpp::simtime_t emitted_time = -1; + // internal /** Stationary qubit last updated at*/ omnetpp::simtime_t updated_time = -1; diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index 4d99d650c..dc2633bf4 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ using quisp::messages::PhotonicQubit; using quisp::modules::qubit_id::QubitId; using quisp::types::CliffordOperator; using quisp::types::EigenvalueResult; +using quisp::types::MeasurementOutcome; using quisp::types::MeasureXResult; using quisp::types::MeasureYResult; using quisp::types::MeasureZResult; @@ -41,58 +43,7 @@ StationaryQubit::StationaryQubit() : provider(utils::ComponentProvider{this}) {} void StationaryQubit::initialize() { // read and set parameters emission_success_probability = par("emission_success_probability"); - // memory_err.X_error_rate = (double)par("memory_X_error_rate").doubleValue(); - // memory_err.Y_error_rate = (double)par("memory_Y_error_rate").doubleValue(); - // memory_err.Z_error_rate = (double)par("memory_Z_error_rate").doubleValue(); - // memory_err.excitation_error_rate = (double)par("memory_energy_excitation_rate").doubleValue(); - // memory_err.relaxation_error_rate = (double)par("memory_energy_relaxation_rate").doubleValue(); - // memory_err.completely_mixed_rate = (double)par("memory_completely_mixed_rate").doubleValue(); - // memory_err.error_rate = memory_err.X_error_rate + memory_err.Y_error_rate + memory_err.Z_error_rate + memory_err.excitation_error_rate + memory_err.relaxation_error_rate + - // memory_err.completely_mixed_rate; // This is per μs. Memory_Transition_matrix = MatrixXd::Zero(7, 7); - // clang-format off - // Memory_Transition_matrix << - // 1 - memory_err.error_rate, memory_err.X_error_rate, memory_err.Z_error_rate, memory_err.Y_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - // memory_err.X_error_rate, 1 - memory_err.error_rate, memory_err.Y_error_rate, memory_err.Z_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - // memory_err.Z_error_rate, memory_err.Y_error_rate, 1 - memory_err.error_rate, memory_err.X_error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - // memory_err.Y_error_rate, memory_err.Z_error_rate, memory_err.X_error_rate, 1 - memory_err.error_rate, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - // 0, 0, 0, 0, 1 - memory_err.relaxation_error_rate - memory_err.completely_mixed_rate, memory_err.relaxation_error_rate, memory_err.completely_mixed_rate, - // 0, 0, 0, 0, memory_err.excitation_error_rate, 1 - memory_err.excitation_error_rate - memory_err.completely_mixed_rate, memory_err.completely_mixed_rate, - // 0, 0, 0, 0, memory_err.excitation_error_rate, memory_err.relaxation_error_rate, 1 - memory_err.excitation_error_rate - memory_err.relaxation_error_rate; - // clang-format on - // std::cout << "Memory_Transition_matrix = \n " << Memory_Transition_matrix << " done \n"; - - // setSingleQubitGateErrorModel(Hgate_error, "Hgate"); - // setSingleQubitGateErrorModel(Xgate_error, "Xgate"); - // setSingleQubitGateErrorModel(Zgate_error, "Zgate"); - // setTwoQubitGateErrorCeilings(CNOTgate_error, "CNOTgate"); - // setMeasurementErrorModel(Measurement_error); - - // std::cout << Memory_Transition_matrix << "\n"; - - // Set error matrices. This is used in the process of simulating tomography. - // Pauli.X << 0, 1, 1, 0; - // Pauli.Y << 0, Complex(0, -1), Complex(0, 1), 0; - // Pauli.Z << 1, 0, 0, -1; - // Pauli.I << 1, 0, 0, 1; - - // Set measurement operators. This is used in the process of simulating tomography. - // meas_op.X_basis.plus << 0.5, 0.5, 0.5, 0.5; - // meas_op.X_basis.minus << 0.5, -0.5, -0.5, 0.5; - // meas_op.X_basis.plus_ket << 1 / sqrt(2), 1 / sqrt(2); - // meas_op.X_basis.minus_ket << 1 / sqrt(2), -1 / sqrt(2); - // meas_op.X_basis.basis = 'X'; - // meas_op.Z_basis.plus << 1, 0, 0, 0; - // meas_op.Z_basis.minus << 0, 0, 0, 1; - // meas_op.Z_basis.plus_ket << 1, 0; - // meas_op.Z_basis.minus_ket << 0, 1; - // meas_op.Z_basis.basis = 'Z'; - // meas_op.Y_basis.plus << 0.5, Complex(0, -0.5), Complex(0, 0.5), 0.5; - // meas_op.Y_basis.minus << 0.5, Complex(0, 0.5), Complex(0, -0.5), 0.5; - // meas_op.Y_basis.plus_ket << 1 / sqrt(2), Complex(0, 1 / sqrt(2)); - // meas_op.Y_basis.minus_ket << 1 / sqrt(2), -Complex(0, 1 / sqrt(2)); - // meas_op.Y_basis.basis = 'Y'; - // meas_op.identity << 1, 0, 0, 1; // Get parameters from omnet stationary_qubit_address = par("stationary_qubit_address"); @@ -110,15 +61,12 @@ void StationaryQubit::initialize() { auto *backend = provider.getQuantumBackend(); qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationary_qubit_address)); + if (qubit_ref == nullptr) throw std::runtime_error("qubit_ref nullptr error"); + setFree(false); // watch variables to show them in the GUI WATCH(emitted_time); WATCH(updated_time); - WATCH(god_err.has_x_error); - WATCH(god_err.has_z_error); - WATCH(god_err.has_excitation_error); - WATCH(god_err.has_relaxation_error); - WATCH(god_err.has_completely_mixed_error); WATCH(is_busy); } @@ -145,211 +93,22 @@ void StationaryQubit::handleMessage(cMessage *msg) { } } -void StationaryQubit::setSingleQubitGateErrorModel(SingleGateErrorModel &model, std::string gate_name) { - auto err_rate_name = gate_name + std::string("_error_rate"); - auto x_ratio_name = gate_name + std::string("_x_error_ratio"); - auto z_ratio_name = gate_name + std::string("_z_error_ratio"); - auto y_ratio_name = gate_name + std::string("_y_error_ratio"); - model.pauli_error_rate = par(err_rate_name.c_str()).doubleValue(); - auto x_ratio = par(x_ratio_name.c_str()).doubleValue(); - auto z_ratio = par(z_ratio_name.c_str()).doubleValue(); - auto y_ratio = par(y_ratio_name.c_str()).doubleValue(); - - double sum = x_ratio + z_ratio + y_ratio; - if (sum == 0) { - x_ratio = 1.; - z_ratio = 1.; - y_ratio = 1.; - sum = 3.; - } - - model.X_error_rate = model.pauli_error_rate * (x_ratio / sum); - model.Y_error_rate = model.pauli_error_rate * (y_ratio / sum); - model.Z_error_rate = model.pauli_error_rate * (z_ratio / sum); - model.No_error_ceil = 1 - model.pauli_error_rate; - model.X_error_ceil = model.No_error_ceil + model.X_error_rate; - model.Z_error_ceil = model.X_error_ceil + model.Z_error_rate; - model.Y_error_ceil = model.Z_error_ceil + model.Y_error_rate; -} - -void StationaryQubit::setTwoQubitGateErrorCeilings(TwoQubitGateErrorModel &model, std::string gate_name) { - // prepare parameter names - std::string err_rate_name = std::string(gate_name) + std::string("_error_rate"); - auto ix_ratio_name = gate_name + std::string("_ix_error_ratio"); - auto xi_ratio_name = gate_name + std::string("_xi_error_ratio"); - auto xx_rationame = gate_name + std::string("_xx_error_ratio"); - - auto iz_ratio_name = gate_name + std::string("_iz_error_ratio"); - auto zi_ratio_name = gate_name + std::string("_zi_error_ratio"); - auto zz_ratio_name = gate_name + std::string("_zz_error_ratio"); - - auto iy_ratio_name = gate_name + std::string("_iy_error_ratio"); - auto yi_ratio_name = gate_name + std::string("_yi_error_ratio"); - auto yy_ratio_name = gate_name + std::string("_yy_error_ratio"); - - // get error ratios from parameter - model.pauli_error_rate = par(err_rate_name.c_str()).doubleValue(); - double ix_ratio = par(ix_ratio_name.c_str()).doubleValue(); - double xi_ratio = par(xi_ratio_name.c_str()).doubleValue(); - double xx_ratio = par(xx_rationame.c_str()).doubleValue(); - - double iz_ratio = par(iz_ratio_name.c_str()).doubleValue(); - double zi_ratio = par(zi_ratio_name.c_str()).doubleValue(); - double zz_ratio = par(zz_ratio_name.c_str()).doubleValue(); - - double iy_ratio = par(iy_ratio_name.c_str()).doubleValue(); - double yi_ratio = par(yi_ratio_name.c_str()).doubleValue(); - double yy_ratio = par(yy_ratio_name.c_str()).doubleValue(); - - double ratio_sum = ix_ratio + xi_ratio + xx_ratio + iz_ratio + zi_ratio + zz_ratio + iy_ratio + yi_ratio + yy_ratio; - - if (ratio_sum == 0) { - ix_ratio = 1.; - xi_ratio = 1.; - xx_ratio = 1.; - iz_ratio = 1.; - zi_ratio = 1.; - zz_ratio = 1.; - iy_ratio = 1.; - yi_ratio = 1.; - yy_ratio = 1.; - ratio_sum = 9.; - } - - model.IX_error_rate = model.pauli_error_rate * (ix_ratio / ratio_sum); - model.XI_error_rate = model.pauli_error_rate * (xi_ratio / ratio_sum); - model.XX_error_rate = model.pauli_error_rate * (xx_ratio / ratio_sum); - - model.IZ_error_rate = model.pauli_error_rate * (iz_ratio / ratio_sum); - model.ZI_error_rate = model.pauli_error_rate * (zi_ratio / ratio_sum); - model.ZZ_error_rate = model.pauli_error_rate * (zz_ratio / ratio_sum); - - model.IY_error_rate = model.pauli_error_rate * (iy_ratio / ratio_sum); - model.YI_error_rate = model.pauli_error_rate * (yi_ratio / ratio_sum); - model.YY_error_rate = model.pauli_error_rate * (yy_ratio / ratio_sum); - - model.No_error_ceil = 1 - model.pauli_error_rate; - model.IX_error_ceil = model.No_error_ceil + model.IX_error_rate; - model.XI_error_ceil = model.IX_error_ceil + model.XI_error_rate; - model.XX_error_ceil = model.XI_error_ceil + model.XX_error_rate; - - model.IZ_error_ceil = model.XX_error_ceil + model.IZ_error_rate; - model.ZI_error_ceil = model.IZ_error_ceil + model.ZI_error_rate; - model.ZZ_error_ceil = model.ZI_error_ceil + model.ZZ_error_rate; - - model.IY_error_ceil = model.ZZ_error_ceil + model.IY_error_rate; - model.YI_error_ceil = model.IY_error_ceil + model.YI_error_rate; - model.YY_error_ceil = model.YI_error_ceil + model.YY_error_rate; -} - -void StationaryQubit::setMeasurementErrorModel(MeasurementErrorModel &model) { - model.x_error_rate = par("x_measurement_error_rate").doubleValue(); - model.y_error_rate = par("y_measurement_error_rate").doubleValue(); - model.z_error_rate = par("z_measurement_error_rate").doubleValue(); -} - -MeasureXResult StationaryQubit::correlationMeasureX() { - bool error = god_err.has_z_error; - if (dblrand() < Measurement_error.x_error_rate) { - error = !error; - } - return error ? MeasureXResult::HAS_Z_ERROR : MeasureXResult::NO_Z_ERROR; -} - -MeasureYResult StationaryQubit::correlationMeasureY() { - bool error = god_err.has_z_error != god_err.has_x_error; - if (dblrand() < Measurement_error.y_error_rate) { - error = !error; - } - return error ? MeasureYResult::HAS_XZ_ERROR : MeasureYResult::NO_XZ_ERROR; -} - -MeasureZResult StationaryQubit::correlationMeasureZ() { - bool error = god_err.has_x_error; - if (dblrand() < Measurement_error.x_error_rate) { - error = !error; - } - return error ? MeasureZResult::HAS_X_ERROR : MeasureZResult::NO_X_ERROR; -} - -EigenvalueResult StationaryQubit::localMeasureX() { - // the Z error will propagate to its partner; This only works for Bell pair and entanglement swapping for now - if (this->entangled_partner != nullptr && god_err.has_z_error) { - this->entangled_partner->addZerror(); - } - - auto result = EigenvalueResult::PLUS_ONE; - if (dblrand() < 0.5) { - result = EigenvalueResult::MINUS_ONE; - if (this->entangled_partner != nullptr) { - this->entangled_partner->addZerror(); - } - } - if (dblrand() < this->Measurement_error.x_error_rate) { - result = result == EigenvalueResult::PLUS_ONE ? EigenvalueResult::MINUS_ONE : EigenvalueResult::PLUS_ONE; - } - return result; -} - +MeasureXResult StationaryQubit::correlationMeasureX() { return qubit_ref->correlationMeasureX(); } +MeasureYResult StationaryQubit::correlationMeasureY() { return qubit_ref->correlationMeasureY(); } +MeasureZResult StationaryQubit::correlationMeasureZ() { return qubit_ref->correlationMeasureZ(); } +EigenvalueResult StationaryQubit::localMeasureX() { return qubit_ref->localMeasureX(); } EigenvalueResult StationaryQubit::localMeasureY() { error("Not Yet Implemented"); return EigenvalueResult::PLUS_ONE; } - -EigenvalueResult StationaryQubit::localMeasureZ() { - // the X error will propagate to its partner; This only works for Bell pair and entanglement swapping for now - if (this->entangled_partner != nullptr && god_err.has_x_error) { - this->entangled_partner->addXerror(); - } - - auto result = EigenvalueResult::PLUS_ONE; - if (dblrand() < 0.5) { - result = EigenvalueResult::MINUS_ONE; - if (this->entangled_partner != nullptr) { - this->entangled_partner->addXerror(); - } - } - if (dblrand() < this->Measurement_error.z_error_rate) { - result = result == EigenvalueResult::PLUS_ONE ? EigenvalueResult::MINUS_ONE : EigenvalueResult::PLUS_ONE; - } - return result; -} +EigenvalueResult StationaryQubit::localMeasureZ() { return qubit_ref->localMeasureZ(); } // Convert X to Z, and Z to X error. Therefore, Y error stays as Y. -void StationaryQubit::Hadamard_gate() { - // Need to add noise here later - applySingleQubitGateError(Hgate_error); - bool z = god_err.has_z_error; - god_err.has_z_error = god_err.has_x_error; - god_err.has_x_error = z; -} - -void StationaryQubit::Z_gate() { - // Need to add noise here later - applySingleQubitGateError(Zgate_error); - god_err.has_z_error = !god_err.has_z_error; -} - -void StationaryQubit::X_gate() { - // Need to add noise here later - applySingleQubitGateError(Xgate_error); - god_err.has_x_error = !god_err.has_x_error; -} - -void StationaryQubit::CNOT_gate(IStationaryQubit *control_qubit) { - // Need to add noise here later - applyTwoQubitGateError(CNOTgate_error, check_and_cast(control_qubit)); - - if (control_qubit->god_err.has_x_error) { - // X error propagates from control to target. If an X error is already present, then it cancels out. - god_err.has_x_error = !god_err.has_x_error; - } +void StationaryQubit::Hadamard_gate() { qubit_ref->gateH(); } +void StationaryQubit::Z_gate() { qubit_ref->gateZ(); } +void StationaryQubit::X_gate() { qubit_ref->gateX(); } - if (god_err.has_z_error) { - // Z error propagates from target to control. If an Z error is already present, then it cancels out. - control_qubit->god_err.has_z_error = !control_qubit->god_err.has_z_error; - } -} +void StationaryQubit::CNOT_gate(IStationaryQubit *control_qubit) { qubit_ref->gateCNOT(check_and_cast(control_qubit)->qubit_ref); } // This is invoked whenever a photon is emitted out from this particular qubit. void StationaryQubit::setBusy() { @@ -501,55 +260,6 @@ void StationaryQubit::setCompletelyMixedDensityMatrix() { } } -// This gets invoked in memory error simulation or by BellStateAnalyzer if photonLoss + darkcount. -void StationaryQubit::setExcitedDensityMatrix() { - Density_Matrix_Collapsed << 1, 0, 0, 0; // Overwrite density matrix - completely_mixed = false; - excited_or_relaxed = true; // It is excited - - god_err.has_excitation_error = true; - god_err.has_relaxation_error = false; - god_err.has_completely_mixed_error = false; - god_err.has_x_error = false; - god_err.has_z_error = false; - GOD_dm_Xerror = false; - GOD_dm_Zerror = false; - if (hasGUI()) { - bubble("Completely mixed. darkcount"); - getDisplayString().setTagArg("i", 1, "white"); - } - - if (this->entangled_partner != nullptr) { // If it used to be entangled... - // error("What?"); - this->entangled_partner->updated_time = simTime(); - // This also eliminates the entanglement information. - this->entangled_partner->setCompletelyMixedDensityMatrix(); - } // else it is already not entangled. e.g. excited -> relaxed. -} - -void StationaryQubit::setRelaxedDensityMatrix() { - Density_Matrix_Collapsed << 0, 0, 0, 1; - completely_mixed = false; - excited_or_relaxed = true; - god_err.has_excitation_error = false; - god_err.has_relaxation_error = true; - god_err.has_completely_mixed_error = false; - god_err.has_x_error = false; - god_err.has_z_error = false; - GOD_dm_Xerror = false; - GOD_dm_Zerror = false; - if (hasGUI()) { - bubble("Completely mixed. darkcount"); - getDisplayString().setTagArg("i", 1, "white"); - } - - // Still entangled - if (this->entangled_partner != nullptr) { - this->entangled_partner->updated_time = simTime(); - this->entangled_partner->setCompletelyMixedDensityMatrix(); - } // else it is already not entangled. e.g. excited -> relaxed. -} - void StationaryQubit::setEntangledPartnerInfo(IStationaryQubit *partner) { // When BSA succeeds, this method gets invoked to store entangled partner information. // This will also be sent classically to the partner node afterwards. @@ -568,167 +278,11 @@ void StationaryQubit::addZerror() { this->god_err.has_z_error = !this->god_err.h // Only tracks error propagation. If two booleans (Alice and Bob) agree (truetrue or falsefalse), keep the purified ebit. bool StationaryQubit::Xpurify(IStationaryQubit *resource_qubit /*Controlled*/) { - // std::cout<<"X puri\n"; - // This could result in completelty mixed, excited, relaxed, which also affects the entangled partner. - applyMemoryError(); - check_and_cast(resource_qubit)->applyMemoryError(); - /*Target qubit*/ this->CNOT_gate(resource_qubit /*controlled qubit*/); - bool meas = this->correlationMeasureZ() == MeasureZResult::NO_X_ERROR; - return meas; -} - -bool StationaryQubit::Zpurify(IStationaryQubit *resource_qubit /*Target*/) { - applyMemoryError(); // This could result in completelty mixed, excited, relaxed, which also affects the entangled partner. - check_and_cast(resource_qubit)->applyMemoryError(); - /*Target qubit*/ resource_qubit->CNOT_gate(this /*controlled qubit*/); - this->Hadamard_gate(); - bool meas = this->correlationMeasureZ() == MeasureZResult::NO_X_ERROR; - return meas; -} - -// Single qubit memory error based on Markov-Chain -void StationaryQubit::applyMemoryError() { - if (entangled_partner == nullptr && Density_Matrix_Collapsed(0, 0).real() == -111 && !no_density_matrix_nullptr_entangled_partner_ok) - error("This must not happen in apply memory error"); - - // If no memory error occurs, or if the state is completely mixed, skip this memory error simulation. - if (memory_err.error_rate == 0) { - // error("memory error is set to 0. If on purpose, that is fine. Comment this out."); - return; - } - - // Check when the error got updated last time. - // Errors will be performed depending on the difference between that time and the current time. - double time_evolution = simTime().dbl() - updated_time.dbl(); - double time_evolution_microsec = time_evolution * 1000000 /** 100*/; - if (time_evolution_microsec > 0) { - // Perform Monte-Carlo error simulation on this qubit. - bool has_x_err = god_err.has_x_error; - bool has_z_err = god_err.has_z_error; - bool is_excited = god_err.has_excitation_error; - bool is_relaxed = god_err.has_relaxation_error; - bool is_completely_mixed = god_err.has_completely_mixed_error; - if (completely_mixed != is_completely_mixed) { - error("[apply_memory_error] Completely mixed flag not matching"); - } - if (excited_or_relaxed != is_excited && excited_or_relaxed != is_relaxed) { - error("[apply_memory_error] Relaxed/Excited flag not matching"); - } - - bool skip_exponentiation = false; - for (int i = 0; i < Memory_Transition_matrix.cols(); i++) { - if (Memory_Transition_matrix(0, i) == 1) { - // Do not to the exponentiation! Eigen will mess up the exponentiation anyway... - skip_exponentiation = true; - break; - } - } - - MatrixXd transition_mat(7, 7); - if (!skip_exponentiation) { - // calculate time evoluted error matrix: Q^(time_evolution_microsec) in Eq 5.3 - MatrixPower q_pow(Memory_Transition_matrix); - transition_mat = q_pow(time_evolution_microsec); - } else { - transition_mat = Memory_Transition_matrix; - } + if (qubit_ref == nullptr) throw std::runtime_error("qubit_ref nullptr error"); - // validate transition_mat - for (int r = 0; r < transition_mat.rows(); r++) { - double col_sum = 0; - for (int i = 0; i < transition_mat.cols(); i++) { - col_sum += transition_mat(r, i); - } - if (col_sum > 1.01 || col_sum < 0.99) { - std::cout << "col_sum = " << col_sum << std::endl; - error("Row of the transition matrix does not sum up to 1."); - } - } + return qubit_ref->purifyX(check_and_cast(resource_qubit)->qubit_ref); } - if (std::isnan(transition_mat(0, 0))) { - std::cout << "transition_mat: " << transition_mat << std::endl; - error("Transition maatrix is NaN. This is Eigen's fault."); - } - - // pi(0 ~ 6) vector in Eq 5.3 - MatrixXd pi_vector(1, 7); // I, X, Z, Y, Ex, Re, Cm - if (is_excited) { - pi_vector << 0, 0, 0, 0, 1, 0, 0; // excitation error - } else if (is_relaxed) { - pi_vector << 0, 0, 0, 0, 0, 1, 0; // relaxation error - } else if (is_completely_mixed) { - pi_vector << 0, 0, 0, 0, 0, 0, 1; // completely mixed error - } else if (has_z_err && has_x_err) { - pi_vector << 0, 0, 0, 1, 0, 0, 0; // Y error - } else if (has_z_err && !has_x_err) { - pi_vector << 0, 0, 1, 0, 0, 0, 0; // Z error - } else if (!has_z_err && has_x_err) { - pi_vector << 0, 1, 0, 0, 0, 0, 0; // X error - } else { - pi_vector << 1, 0, 0, 0, 0, 0, 0; // No error - } - // pi(t) in Eq 5.3 - // Clean, X, Z, Y, Excited, Relaxed - MatrixXd output_vector(1, 6); - // take error rate vector from DynamicTransitionMatrix Eq 5.3 - output_vector = pi_vector * transition_mat; - - /* this prepares the sectors for Monte-Carlo. later, we'll pick a random value and check with this sectors. - * - * 0.0 clean_ceil z_ceil excited_ceil 1.0 - * | | | | | - * | No Error | X Error | Z Error | Y Error | Excitation | Relaxation | Cmpletely Mixed | - * | | | - * x_ceil y_ceil relaxed_ceil - */ - double clean_ceil = output_vector(0, 0); - double x_ceil = clean_ceil + output_vector(0, 1); - double z_ceil = x_ceil + output_vector(0, 2); - double y_ceil = z_ceil + output_vector(0, 3); - double excited_ceil = y_ceil + output_vector(0, 4); - double relaxed_ceil = excited_ceil + output_vector(0, 5); - - // Gives a random double between 0.0 ~ 1.0 - double rand = dblrand(); - - if (rand < clean_ceil) { - // Qubit will end up with no error - god_err.has_x_error = false; - god_err.has_z_error = false; - } else if (clean_ceil <= rand && rand < x_ceil && (clean_ceil != x_ceil)) { - // X error - god_err.has_x_error = true; - god_err.has_z_error = false; - } else if (x_ceil <= rand && rand < z_ceil && (x_ceil != z_ceil)) { - // Z error - god_err.has_x_error = false; - god_err.has_z_error = true; - } else if (z_ceil <= rand && rand < y_ceil && (z_ceil != y_ceil)) { - // Y error - god_err.has_x_error = true; - god_err.has_z_error = true; - } else if (y_ceil <= rand && rand < excited_ceil && (y_ceil != excited_ceil)) { - // Excitation error - // Also sets the partner completely mixed if it used to be entangled. - setExcitedDensityMatrix(); - } else if (excited_ceil <= rand && rand < relaxed_ceil && (excited_ceil != relaxed_ceil)) { - // Excitation error - // Also sets the partner completely mixed if it used to be entangled. - setRelaxedDensityMatrix(); - } else { - // Memory completely mixed error - - // If this qubit still used to be entangled with another qubit. - if (entangled_partner != nullptr) { - entangled_partner->updated_time = simTime(); - // Break entanglement with partner. Overwrite its density matrix. - entangled_partner->setCompletelyMixedDensityMatrix(); - } - setCompletelyMixedDensityMatrix(); - } - } - updated_time = simTime(); -} +bool StationaryQubit::Zpurify(IStationaryQubit *resource_qubit /*Target*/) { return qubit_ref->purifyZ(check_and_cast(resource_qubit)->qubit_ref); } Matrix2cd StationaryQubit::getErrorMatrix(StationaryQubit *qubit) { if (qubit->god_err.has_completely_mixed_error || qubit->god_err.has_relaxation_error) { @@ -744,316 +298,7 @@ Matrix2cd StationaryQubit::getErrorMatrix(StationaryQubit *qubit) { return Pauli.I; } -// returns the density matrix of the Bell pair with error. This assumes that this is entangled with another stationary qubit. -// Measurement output will be based on this matrix, as long as it is still entangled. -quantum_state StationaryQubit::getQuantumState() { - if (this->excited_or_relaxed) error("this qubit is excited or relaxed"); - if (this->entangled_partner == nullptr) error("no entangled partner"); - if (this->entangled_partner->excited_or_relaxed) error("partner qubit is excited or relaxed"); - - Matrix4cd error_mat = kroneckerProduct(getErrorMatrix(this), getErrorMatrix(check_and_cast(entangled_partner))).eval(); - // Assumes that the state is a 2 qubit state |00> + |11> - Vector4cd ideal_bell_state(1 / sqrt(2), 0, 0, 1 / sqrt(2)); - Vector4cd actual_bell_state = error_mat * ideal_bell_state; - - quantum_state q; - q.state_in_density_matrix = actual_bell_state * actual_bell_state.adjoint(); - q.state_in_ket = actual_bell_state; - return q; -} - -void StationaryQubit::applySingleQubitGateError(SingleGateErrorModel const &err) { - if (err.pauli_error_rate == 0) { - return; - } - // Gives a random double between 0.0 ~ 1.0 - double rand = dblrand(); - - /* - * 0.0 No_error_ceil Z_error_ceil 1.0 - * | | | | - * | No Error | X Error | Z Error | Y Error | - * | - * X_error_ceil - */ - if (rand <= err.No_error_ceil) { - // No error - } else if (err.No_error_ceil < rand && rand <= err.X_error_ceil && (err.No_error_ceil != err.X_error_ceil)) { - // X error - addXerror(); - } else if (err.X_error_ceil < rand && rand <= err.Z_error_ceil && (err.X_error_ceil != err.Z_error_ceil)) { - // Z error - addZerror(); - } else { - // Y error - addZerror(); - addXerror(); - } -} - -void StationaryQubit::applyTwoQubitGateError(TwoQubitGateErrorModel const &err, StationaryQubit *another_qubit) { - if (err.pauli_error_rate == 0) { - return; - } - - // Gives a random double between 0.0 ~ 1.0 - double rand = dblrand(); - - /* - * 0.0 No_error_ceil XI_error_ceil IY_error_ceil YY_error_ceil ZI_error_ceil 1.0 - * | | | | | | | - * | No err | IX err | XI err | XX err | IY err | YI err | YY err | IZ err | ZI err | ZZ err | - * | | | | - * IX_error_ceil XX_error_ceil YI_error_ceil IZ_error_ceil - */ - if (rand <= err.No_error_ceil) { - // No error - } else if (err.No_error_ceil < rand && rand <= err.IX_error_ceil && (err.No_error_ceil != err.IX_error_ceil)) { - // IX error - addXerror(); - } else if (err.IX_error_ceil < rand && rand <= err.XI_error_ceil && (err.IX_error_ceil != err.XI_error_ceil)) { - // XI error - another_qubit->addXerror(); - } else if (err.XI_error_ceil < rand && rand <= err.XX_error_ceil && (err.XI_error_ceil != err.XX_error_ceil)) { - // XX error - addXerror(); - another_qubit->addXerror(); - } else if (err.XX_error_ceil < rand && rand <= err.IZ_error_ceil && (err.XX_error_ceil != err.IZ_error_ceil)) { - // IZ error - addZerror(); - } else if (err.IZ_error_ceil < rand && rand <= err.ZI_error_ceil && (err.IZ_error_ceil != err.ZI_error_ceil)) { - // ZI error - another_qubit->addZerror(); - } else if (err.ZI_error_ceil < rand && rand <= err.ZZ_error_ceil && (err.ZI_error_ceil != err.ZZ_error_ceil)) { - // ZZ error - addZerror(); - another_qubit->addZerror(); - } else if (err.ZZ_error_ceil < rand && rand <= err.IY_error_ceil && (err.ZZ_error_ceil != err.IY_error_ceil)) { - // IY error - addXerror(); - addZerror(); - } else if (err.IY_error_ceil < rand && rand <= err.YI_error_ceil && (err.IY_error_ceil != err.YI_error_ceil)) { - // YI error - another_qubit->addXerror(); - another_qubit->addZerror(); - } else { - // YY error - addXerror(); - addZerror(); - another_qubit->addXerror(); - another_qubit->addZerror(); - } -} - -measurement_outcome StationaryQubit::measure_density_independent() { - if (this->entangled_partner == nullptr && this->Density_Matrix_Collapsed(0, 0).real() == -111) { - std::cout << Density_Matrix_Collapsed << "\n"; - std::cout << "Measuring" << this << "in node[" << node_address << "]\n"; - std::cout << this->getIndex() << "\n"; - error("Measuring a qubit that is not entangled with another qubit. Probably not what you want! Check whether address for each node is unique!!!"); - } - measurement_operator this_measurement = Random_Measurement_Basis_Selection(); // Select basis randomly - char Output; - bool Output_is_plus; - - // Add memory error depending on the idle time. If excited/relaxed, this will immediately break entanglement, leaving the other qubit as completely mixed. - applyMemoryError(); - - // This becomes nullptr if this qubit got excited/relaxed or measured. - if (this->entangled_partner != nullptr) { - if (this->entangled_partner->entangled_partner == nullptr) { - std::cout << "Entanglement not tracked well between partners." << this << " in node[" << node_address << "]\n"; - std::cout << "Partner must be " << this->entangled_partner << " in node[" << this->entangled_partner->node_address << "]\n"; - error("NO!"); - } - if (this->partner_measured) error("Entangled partner not nullptr but partner already measured....? Probably wrong."); - if (this->completely_mixed || this->excited_or_relaxed) { - std::cout << "[Error]" << this << "\n"; - error("Entangled but completely mixed / Excited / Relaxed ? Probably wrong."); - } - // Also do the same on the partner if it is still entangled! This could break the entanglement due to relaxation/excitation error! - check_and_cast(this->entangled_partner)->applyMemoryError(); - } - - /*-For debugging-*/ - char GOD_state = 'F'; // Completely mixed - - if (this->god_err.has_excitation_error) - GOD_state = 'E'; - else if (this->god_err.has_excitation_error) - GOD_state = 'R'; - else if (this->god_err.has_completely_mixed_error) - GOD_state = 'C'; - else if (!this->god_err.has_x_error && this->god_err.has_z_error) // To check stabilizers.... - GOD_state = 'Z'; - else if (this->god_err.has_x_error && !this->god_err.has_z_error) - GOD_state = 'X'; - else if (this->god_err.has_x_error && this->god_err.has_z_error) - GOD_state = 'Y'; - - /*---------------*/ - - if (this->completely_mixed != this->god_err.has_completely_mixed_error) { - error("Cm track wrong\n"); - } - if (this->excited_or_relaxed && !this->god_err.has_excitation_error && !this->god_err.has_relaxation_error) { - std::cout << "this->excited_or_relaxed = " << this->excited_or_relaxed << ", !this->god_err.has_relaxation_error=" << !this->god_err.has_relaxation_error - << "!this->god_err.has_excitation_error=" << !this->god_err.has_excitation_error; - error("Ex/Re track wrong\n"); - } - // if there is an entanglement - if (this->entangled_partner != nullptr) { - // This qubit is nullptr - if (this->entangled_partner->entangled_partner == nullptr) { - error("Entangled_partner track wrong\n"); - } - // check completely mixed tracking - if (this->entangled_partner->completely_mixed != this->entangled_partner->god_err.has_completely_mixed_error) { - error("Partner Cm track wrong\n"); - } - // check excited and relaxation tracking - if (this->entangled_partner->excited_or_relaxed && !this->entangled_partner->god_err.has_excitation_error && !this->entangled_partner->god_err.has_relaxation_error) { - error("Partner Re/Ex track wrong\n"); - } - if (this->entangled_partner->god_err.has_completely_mixed_error || this->entangled_partner->god_err.has_relaxation_error || - this->entangled_partner->god_err.has_excitation_error) { - // error("Partner CM/Re/Ex track wrong\n"); - } - } - - // if the partner qubit is measured, - if (this->partner_measured || this->completely_mixed || this->excited_or_relaxed) { // The case when the density matrix is completely local to this qubit. - // if this qubit is said to be completely mixed and no set value - if (this->completely_mixed && !this->god_err.has_completely_mixed_error) { - error("Mismatch between flags."); - } - if (this->Density_Matrix_Collapsed(0, 0).real() == -111) { // We always need some kind of density matrix inside this if statement. - error("Single qubit density matrix not stored properly after partner's measurement, excitation/relaxation error."); - } - bool Xerr = this->god_err.has_x_error; - bool Zerr = this->god_err.has_z_error; - // This qubit's density matrix was created when the partner measured his own. - // Because this qubit can be measured after that, we need to update the stored density matrix according to new errors occurred due to memory error. - - if (Xerr != GOD_dm_Xerror) { // Another X error to the dm. - // error("NO"); - Density_Matrix_Collapsed = Pauli.X * Density_Matrix_Collapsed * Pauli.X.adjoint(); - } - if (Zerr != GOD_dm_Zerror) { // Another Z error to the dm. - // error("NO!"); - Density_Matrix_Collapsed = Pauli.Z * Density_Matrix_Collapsed * Pauli.Z.adjoint(); - } - - // std::cout<<"Not entangled anymore. Density matrix is "<partner_measured && !this->completely_mixed && !this->excited_or_relaxed && this->entangled_partner != nullptr) { - // This is assuming that this is some other qubit is entangled. Only Pauli errors are assumed. - quantum_state current_state = getQuantumState(); - EV << "Current entangled state is " << current_state.state_in_ket << "\n"; - - bool Xerr = this->god_err.has_x_error; - bool Zerr = this->god_err.has_z_error; - // std::cout<<"Entangled state is "<Density_Matrix_Collapsed = normalized_partners_dm; - - // We actually do not need this as long as deleting entangled_partner completely is totally fine. - entangled_partner->partner_measured = true; - // if(entangled_partner->getIndex() == 71 && entangled_partner->node_address == 3) - // std::cout<<"-------------------"<node_address<<"] overwritten dm.\n"; - - // Break entanglement. - entangled_partner->entangled_partner = nullptr; - // Save what error it had, when this density matrix was calculated. - // Error may get updated in the future, so we need to track what error has been considered already in the dm. - entangled_partner->GOD_dm_Xerror = entangled_partner->god_err.has_x_error; - entangled_partner->GOD_dm_Zerror = entangled_partner->god_err.has_z_error; - } else { - error("Check condition in measure func."); - } - - // add measurement error - auto rand_num = dblrand(); - if (this_measurement.basis == meas_op.X_basis.basis && rand_num < Measurement_error.x_error_rate || - this_measurement.basis == meas_op.Y_basis.basis && rand_num < Measurement_error.y_error_rate || - this_measurement.basis == meas_op.Z_basis.basis && rand_num < Measurement_error.z_error_rate) { - Output_is_plus = !Output_is_plus; - } - - measurement_outcome o; - o.basis = this_measurement.basis; - o.outcome_is_plus = Output_is_plus; - o.GOD_clean = GOD_state; - return o; -} - -measurement_operator StationaryQubit::Random_Measurement_Basis_Selection() { - measurement_operator this_measurement; - double dbl = dblrand(); // Random double value for random basis selection. - EV << "Random dbl = " << dbl << "! \n "; - - if (dbl < ((double)1 / (double)3)) { // X measurement! - EV << "X measurement\n"; - this_measurement.plus = meas_op.X_basis.plus; - this_measurement.minus = meas_op.X_basis.minus; - this_measurement.basis = meas_op.X_basis.basis; - this_measurement.plus_ket = meas_op.X_basis.plus_ket; - this_measurement.minus_ket = meas_op.X_basis.minus_ket; - } else if (dbl >= ((double)1 / (double)3) && dbl < ((double)2 / (double)3)) { - EV << "Z measurement\n"; - this_measurement.plus = meas_op.Z_basis.plus; - this_measurement.minus = meas_op.Z_basis.minus; - this_measurement.basis = meas_op.Z_basis.basis; - this_measurement.plus_ket = meas_op.Z_basis.plus_ket; - this_measurement.minus_ket = meas_op.Z_basis.minus_ket; - } else { - EV << "Y measurement\n"; - this_measurement.plus = meas_op.Y_basis.plus; - this_measurement.minus = meas_op.Y_basis.minus; - this_measurement.basis = meas_op.Y_basis.basis; - this_measurement.plus_ket = meas_op.Y_basis.plus_ket; - this_measurement.minus_ket = meas_op.Y_basis.minus_ket; - } - return this_measurement; -} +MeasurementOutcome StationaryQubit::measure_density_independent() { return qubit_ref->measureDensityIndependent(); } // protected internal graph backend functions diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index 90aa7ce8e..c9f222a76 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -97,14 +97,14 @@ class StationaryQubit : public IStationaryQubit { virtual types::EigenvalueResult localMeasureY() override; virtual types::EigenvalueResult localMeasureZ() override; - virtual types::EigenvalueResult measureX() override; - virtual types::EigenvalueResult measureY() override; - virtual types::EigenvalueResult measureZ() override; + virtual types::EigenvalueResult measureX(); + virtual types::EigenvalueResult measureY(); + virtual types::EigenvalueResult measureZ(); /** * Performs measurement and returns +(true) or -(false) based on the density matrix of the state. Used for tomography. * */ // virtual std::bitset<1> measure_density(char basis_this_qubit);/*Simultaneous dm calculation*/ - virtual measurement_outcome measure_density_independent() override; /*Separate dm calculation*/ + virtual types::MeasurementOutcome measure_density_independent() override; /*Separate dm calculation*/ /** * \brief Two qubit CNOT gate. @@ -134,19 +134,14 @@ class StationaryQubit : public IStationaryQubit { /*GOD parameters*/ void setEntangledPartnerInfo(IStationaryQubit *partner) override; - void setCompletelyMixedDensityMatrix() override; + void setCompletelyMixedDensityMatrix(); void setRelaxedDensityMatrix(); void setExcitedDensityMatrix(); - void addXerror() override; - void addZerror() override; + void addXerror(); + void addZerror(); double emission_success_probability; - SingleGateErrorModel Hgate_error; - SingleGateErrorModel Xgate_error; - SingleGateErrorModel Zgate_error; - TwoQubitGateErrorModel CNOTgate_error; - MeasurementErrorModel Measurement_error; memory_error_model memory_err; single_qubit_error Pauli; @@ -170,14 +165,7 @@ class StationaryQubit : public IStationaryQubit { // returns the dm of the physical Bell pair. Used for tomography. quantum_state getQuantumState(); measurement_operator Random_Measurement_Basis_Selection(); - void setSingleQubitGateErrorModel(SingleGateErrorModel &model, std::string gate_name); - void setTwoQubitGateErrorCeilings(TwoQubitGateErrorModel &model, std::string gate_name); void setMeasurementErrorModel(MeasurementErrorModel &model); - /*Applies memory error to the given qubit*/ - void applyMemoryError(); - - void applySingleQubitGateError(SingleGateErrorModel const &err); - void applyTwoQubitGateError(TwoQubitGateErrorModel const &err, StationaryQubit *another_qubit); // this is for debugging. class internal use only. // and it's different from QubitRecord's one. diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc index aecdba91c..d4eedc302 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc @@ -9,577 +9,589 @@ using namespace quisp::modules; using namespace quisp::modules::common; using namespace quisp_test; namespace { -class Strategy : public TestComponentProviderStrategy { - public: - Strategy() : backend(new MockQuantumBackend()) {} - ~Strategy() {} - IQuantumBackend *getQuantumBackend() override { return backend; } - MockQuantumBackend *backend; -}; - -class StatQubitTarget : public StationaryQubit { - public: - using StationaryQubit::applySingleQubitGateError; - using StationaryQubit::applyTwoQubitGateError; - using StationaryQubit::initialize; - using StationaryQubit::par; - using StationaryQubit::setSingleQubitGateErrorModel; - using StationaryQubit::setTwoQubitGateErrorCeilings; - StatQubitTarget() : StationaryQubit() { - setComponentType(new TestModuleType("test qubit")); - provider.setStrategy(std::make_unique()); - } - void reset() { - setFree(true); - updated_time = SimTime(0); - no_density_matrix_nullptr_entangled_partner_ok = true; - } - void fillParams() { - setParDouble(this, "emission_success_probability", 0.5); - setParDouble(this, "memory_x_error_rate", 1.11111111e-7); - setParDouble(this, "memory_y_error_rate", 1.11111111e-7); - setParDouble(this, "memory_z_error_rate", 1.11111111e-7); - setParDouble(this, "memory_energy_excitation_rate", 0.000198); - setParDouble(this, "memory_energy_relaxation_rate", 0.00000198); - setParDouble(this, "memory_completely_mixed_rate", 0); - - // No error= 0.4, X error = 0.6, Z error = 0.8, Y error = 1.0 - setParDouble(this, "h_gate_error_rate", 0.6); - setParDouble(this, "h_gate_x_error_ratio", 1); - setParDouble(this, "h_gate_z_error_ratio", 1); - setParDouble(this, "h_gate_y_error_ratio", 1); - - setParDouble(this, "x_gate_error_rate", 0.6); - setParDouble(this, "x_gate_x_error_ratio", 1); - setParDouble(this, "x_gate_z_error_ratio", 1); - setParDouble(this, "x_gate_y_error_ratio", 1); - - setParDouble(this, "z_gate_error_rate", 0.6); - setParDouble(this, "z_gate_x_error_ratio", 1); - setParDouble(this, "z_gate_z_error_ratio", 1); - setParDouble(this, "z_gate_y_error_ratio", 1); - - // clean = 0.1, - // IX = 0.2, XI = 0.3, XX = 0.4, - // IZ = 0.5, ZI = 0.6, ZZ = 0.7, - // IY = 0.8, IY = 0.9, YY = 1.0 - setParDouble(this, "cnot_gate_error_rate", 0.9); - setParDouble(this, "cnot_gate_ix_error_ratio", 1); - setParDouble(this, "cnot_gate_xi_error_ratio", 1); - setParDouble(this, "cnot_gate_xx_error_ratio", 1); - setParDouble(this, "cnot_gate_iz_error_ratio", 1); - setParDouble(this, "cnot_gate_zi_error_ratio", 1); - setParDouble(this, "cnot_gate_zz_error_ratio", 1); - setParDouble(this, "cnot_gate_iy_error_ratio", 1); - setParDouble(this, "cnot_gate_yi_error_ratio", 1); - setParDouble(this, "cnot_gate_yy_error_ratio", 1); - - setParDouble(this, "x_measurement_error_rate", 1.0 / 2000); - setParDouble(this, "y_measurement_error_rate", 1.0 / 2000); - setParDouble(this, "z_measurement_error_rate", 1.0 / 2000); - - setParInt(this, "stationary_qubit_address", 1); - setParInt(this, "node_address", 1); - setParInt(this, "qnic_address", 1); - setParInt(this, "qnic_type", 0); - setParInt(this, "qnic_index", 0); - setParDouble(this, "emission_jittering_standard_deviation", 0.5); - } -}; - -TEST(StatQubitGateErrorTest, SetSingleQubitGateErrorCeilings) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - setParDouble(qubit, "x_gate_error_rate", 0.1); - setParDouble(qubit, "x_gate_x_error_ratio", 1); - setParDouble(qubit, "x_gate_z_error_ratio", 2); - setParDouble(qubit, "x_gate_y_error_ratio", 3); - sim->registerComponent(qubit); - qubit->setSingleQubitGateErrorModel(qubit->Xgate_error, std::string("x_gate")); - auto &error_model = qubit->Xgate_error; - EXPECT_FALSE(std::isnan(error_model.X_error_rate)); - EXPECT_FALSE(std::isnan(error_model.Y_error_rate)); - EXPECT_FALSE(std::isnan(error_model.Z_error_rate)); - EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.X_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.Z_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.Y_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.X_error_rate)); - EXPECT_FALSE(std::isinf(error_model.Y_error_rate)); - EXPECT_FALSE(std::isinf(error_model.Z_error_rate)); - EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.X_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.Z_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.Y_error_ceil)); - EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); - EXPECT_DOUBLE_EQ(error_model.X_error_rate, 0.1 * 1 / 6); - EXPECT_DOUBLE_EQ(error_model.Z_error_rate, 0.2 * 1 / 6); - EXPECT_DOUBLE_EQ(error_model.Y_error_rate, 0.3 * 1 / 6); -} - -TEST(StatQubitGateErrorTest, SetSingleQubitGateErrorCeilings_div_by_zero) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - setParDouble(qubit, "x_gate_error_rate", 0.1); - setParDouble(qubit, "x_gate_x_error_ratio", 0); - setParDouble(qubit, "x_gate_z_error_ratio", 0); - setParDouble(qubit, "x_gate_y_error_ratio", 0); - sim->registerComponent(qubit); - qubit->setSingleQubitGateErrorModel(qubit->Xgate_error, std::string("x_gate")); - auto &error_model = qubit->Xgate_error; - EXPECT_FALSE(std::isnan(error_model.X_error_rate)); - EXPECT_FALSE(std::isnan(error_model.Y_error_rate)); - EXPECT_FALSE(std::isnan(error_model.Z_error_rate)); - EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.X_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.Z_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.Y_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.X_error_rate)); - EXPECT_FALSE(std::isinf(error_model.Y_error_rate)); - EXPECT_FALSE(std::isinf(error_model.Z_error_rate)); - EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.X_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.Z_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.Y_error_ceil)); - EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); - EXPECT_DOUBLE_EQ(error_model.X_error_rate, 0.1 * 1 / 3); - EXPECT_DOUBLE_EQ(error_model.Z_error_rate, 0.1 * 1 / 3); - EXPECT_DOUBLE_EQ(error_model.Y_error_rate, 0.1 * 1 / 3); -} - -TEST(StatQubitGateErrorTest, SetTwoQubitGateErrorCeilings) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - setParDouble(qubit, "cnot_gate_error_rate", 0.1); - setParDouble(qubit, "cnot_gate_ix_error_ratio", 1); - setParDouble(qubit, "cnot_gate_xi_error_ratio", 1); - setParDouble(qubit, "cnot_gate_xx_error_ratio", 1); - setParDouble(qubit, "cnot_gate_iz_error_ratio", 1); - setParDouble(qubit, "cnot_gate_zi_error_ratio", 1); - setParDouble(qubit, "cnot_gate_zz_error_ratio", 1); - setParDouble(qubit, "cnot_gate_iy_error_ratio", 1); - setParDouble(qubit, "cnot_gate_yi_error_ratio", 1); - setParDouble(qubit, "cnot_gate_yy_error_ratio", 1); - sim->registerComponent(qubit); - qubit->setTwoQubitGateErrorCeilings(qubit->CNOTgate_error, std::string("cnot_gate")); - auto const &error_model = qubit->CNOTgate_error; - EXPECT_FALSE(std::isnan(error_model.IX_error_rate)); - EXPECT_FALSE(std::isnan(error_model.XI_error_rate)); - EXPECT_FALSE(std::isnan(error_model.XX_error_rate)); - EXPECT_FALSE(std::isnan(error_model.IZ_error_rate)); - EXPECT_FALSE(std::isnan(error_model.ZI_error_rate)); - EXPECT_FALSE(std::isnan(error_model.ZZ_error_rate)); - EXPECT_FALSE(std::isnan(error_model.IY_error_rate)); - EXPECT_FALSE(std::isnan(error_model.YI_error_rate)); - EXPECT_FALSE(std::isnan(error_model.YY_error_rate)); - EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.XI_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.IX_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.XX_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.ZI_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.IZ_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.ZZ_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.YI_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.IY_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.YY_error_ceil)); - - EXPECT_FALSE(std::isinf(error_model.XI_error_rate)); - EXPECT_FALSE(std::isinf(error_model.IX_error_rate)); - EXPECT_FALSE(std::isinf(error_model.XX_error_rate)); - EXPECT_FALSE(std::isinf(error_model.ZI_error_rate)); - EXPECT_FALSE(std::isinf(error_model.IZ_error_rate)); - EXPECT_FALSE(std::isinf(error_model.ZZ_error_rate)); - EXPECT_FALSE(std::isinf(error_model.YI_error_rate)); - EXPECT_FALSE(std::isinf(error_model.IY_error_rate)); - EXPECT_FALSE(std::isinf(error_model.YY_error_rate)); - EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.XI_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.IX_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.XX_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.ZI_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.IZ_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.ZZ_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.YI_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.IY_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.YY_error_ceil)); - EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); - EXPECT_DOUBLE_EQ(error_model.XI_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.IX_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.XX_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.ZI_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.IZ_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.ZZ_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.YI_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.IY_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.YY_error_rate, 0.1 * 1 / 9); -} - -TEST(StatQubitGateErrorTest, SetTwoQubitGateErrorCeilings_div_by_zero) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - setParDouble(qubit, "cnot_gate_error_rate", 0.1); - setParDouble(qubit, "cnot_gate_ix_error_ratio", 0); - setParDouble(qubit, "cnot_gate_xi_error_ratio", 0); - setParDouble(qubit, "cnot_gate_xx_error_ratio", 0); - setParDouble(qubit, "cnot_gate_iz_error_ratio", 0); - setParDouble(qubit, "cnot_gate_zi_error_ratio", 0); - setParDouble(qubit, "cnot_gate_zz_error_ratio", 0); - setParDouble(qubit, "cnot_gate_iy_error_ratio", 0); - setParDouble(qubit, "cnot_gate_yi_error_ratio", 0); - setParDouble(qubit, "cnot_gate_yy_error_ratio", 0); - sim->registerComponent(qubit); - qubit->setTwoQubitGateErrorCeilings(qubit->CNOTgate_error, std::string("cnot_gate")); - auto const &error_model = qubit->CNOTgate_error; - EXPECT_FALSE(std::isnan(error_model.IX_error_rate)); - EXPECT_FALSE(std::isnan(error_model.XI_error_rate)); - EXPECT_FALSE(std::isnan(error_model.XX_error_rate)); - EXPECT_FALSE(std::isnan(error_model.IZ_error_rate)); - EXPECT_FALSE(std::isnan(error_model.ZI_error_rate)); - EXPECT_FALSE(std::isnan(error_model.ZZ_error_rate)); - EXPECT_FALSE(std::isnan(error_model.IY_error_rate)); - EXPECT_FALSE(std::isnan(error_model.YI_error_rate)); - EXPECT_FALSE(std::isnan(error_model.YY_error_rate)); - EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.XI_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.IX_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.XX_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.ZI_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.IZ_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.ZZ_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.YI_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.IY_error_ceil)); - EXPECT_FALSE(std::isnan(error_model.YY_error_ceil)); - - EXPECT_FALSE(std::isinf(error_model.XI_error_rate)); - EXPECT_FALSE(std::isinf(error_model.IX_error_rate)); - EXPECT_FALSE(std::isinf(error_model.XX_error_rate)); - EXPECT_FALSE(std::isinf(error_model.ZI_error_rate)); - EXPECT_FALSE(std::isinf(error_model.IZ_error_rate)); - EXPECT_FALSE(std::isinf(error_model.ZZ_error_rate)); - EXPECT_FALSE(std::isinf(error_model.YI_error_rate)); - EXPECT_FALSE(std::isinf(error_model.IY_error_rate)); - EXPECT_FALSE(std::isinf(error_model.YY_error_rate)); - EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); - EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.XI_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.IX_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.XX_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.ZI_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.IZ_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.ZZ_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.YI_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.IY_error_ceil)); - EXPECT_FALSE(std::isinf(error_model.YY_error_ceil)); - EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); - EXPECT_DOUBLE_EQ(error_model.XI_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.IX_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.XX_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.ZI_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.IZ_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.ZZ_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.YI_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.IY_error_rate, 0.1 * 1 / 9); - EXPECT_DOUBLE_EQ(error_model.YY_error_rate, 0.1 * 1 / 9); -} - -TEST(StatQubitGateErrorTest, do_nothing_single_qubit_gate) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - setParDouble(qubit, "x_gate_error_rate", 0.0); - sim->registerComponent(qubit); - - qubit->callInitialize(); - qubit->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - - qubit->applySingleQubitGateError(qubit->Xgate_error); - - EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); -} - -TEST(StatQubitGateErrorTest, do_nothing_two_qubit_gate) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - auto *qubit2 = new StatQubitTarget{}; - sim->registerComponent(qubit); - sim->registerComponent(qubit2); - - qubit->fillParams(); - qubit2->fillParams(); - setParDouble(qubit, "cnot_gate_error_rate", 0.0); - qubit->callInitialize(); - qubit2->callInitialize(); - qubit->reset(); - qubit2->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; - qubit2->god_err.has_x_error = true; - qubit2->god_err.has_z_error = true; - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit2->god_err.has_x_error); - EXPECT_TRUE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - - qubit->applyTwoQubitGateError(qubit->CNOTgate_error, qubit2); - - EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit2->god_err.has_x_error); - EXPECT_TRUE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); -} - -TEST(StatQubitGateErrorTest, apply_single_qubit_gate_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - sim->registerComponent(qubit); - - qubit->callInitialize(); - sim->setSimTime(SimTime(1, SIMTIME_US)); - // No error - qubit->reset(); - rng->doubleValue = 0.35; - qubit->applySingleQubitGateError(qubit->Xgate_error); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); - - // X error - qubit->reset(); - rng->doubleValue = 0.45; - qubit->applySingleQubitGateError(qubit->Xgate_error); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); - - // Z error - qubit->reset(); - rng->doubleValue = 0.65; - qubit->applySingleQubitGateError(qubit->Xgate_error); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); - - // Y error - qubit->reset(); - rng->doubleValue = 0.85; - qubit->applySingleQubitGateError(qubit->Xgate_error); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); -} - -TEST(StatQubitGateErrorTest, apply_two_qubit_gate_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit1 = new StatQubitTarget{}; - auto *qubit2 = new StatQubitTarget{}; - qubit1->fillParams(); - qubit2->fillParams(); - sim->registerComponent(qubit1); - sim->registerComponent(qubit2); - qubit1->callInitialize(); - qubit2->callInitialize(); - - sim->setSimTime(SimTime(1, SIMTIME_US)); - - // No error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.05; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_FALSE(qubit1->god_err.has_x_error); - EXPECT_FALSE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_FALSE(qubit2->god_err.has_x_error); - EXPECT_FALSE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // IX error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.15; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_TRUE(qubit1->god_err.has_x_error); - EXPECT_FALSE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_FALSE(qubit2->god_err.has_x_error); - EXPECT_FALSE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // XI error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.25; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_FALSE(qubit1->god_err.has_x_error); - EXPECT_FALSE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_TRUE(qubit2->god_err.has_x_error); - EXPECT_FALSE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // XX error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.35; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_TRUE(qubit1->god_err.has_x_error); - EXPECT_FALSE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_TRUE(qubit2->god_err.has_x_error); - EXPECT_FALSE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // IZ error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.45; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_FALSE(qubit1->god_err.has_x_error); - EXPECT_TRUE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_FALSE(qubit2->god_err.has_x_error); - EXPECT_FALSE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // ZI error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.55; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_FALSE(qubit1->god_err.has_x_error); - EXPECT_FALSE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_FALSE(qubit2->god_err.has_x_error); - EXPECT_TRUE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // ZZ error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.65; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_FALSE(qubit1->god_err.has_x_error); - EXPECT_TRUE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_FALSE(qubit2->god_err.has_x_error); - EXPECT_TRUE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // IY error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.75; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_TRUE(qubit1->god_err.has_x_error); - EXPECT_TRUE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_FALSE(qubit2->god_err.has_x_error); - EXPECT_FALSE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // YI error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.85; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_FALSE(qubit1->god_err.has_x_error); - EXPECT_FALSE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_TRUE(qubit2->god_err.has_x_error); - EXPECT_TRUE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); - - // YY error - qubit1->reset(); - qubit2->reset(); - rng->doubleValue = 0.95; - qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); - EXPECT_TRUE(qubit1->god_err.has_x_error); - EXPECT_TRUE(qubit1->god_err.has_z_error); - EXPECT_FALSE(qubit1->god_err.has_excitation_error); - EXPECT_FALSE(qubit1->god_err.has_relaxation_error); - EXPECT_FALSE(qubit1->god_err.has_completely_mixed_error); - EXPECT_TRUE(qubit2->god_err.has_x_error); - EXPECT_TRUE(qubit2->god_err.has_z_error); - EXPECT_FALSE(qubit2->god_err.has_excitation_error); - EXPECT_FALSE(qubit2->god_err.has_relaxation_error); - EXPECT_FALSE(qubit2->god_err.has_completely_mixed_error); -} + +// class Strategy : public TestComponentProviderStrategy { +// public: +// Strategy() : backend(new MockQuantumBackend()) {} +// ~Strategy() {} +// IQuantumBackend *getQuantumBackend() override { return backend; } +// MockQuantumBackend *backend; +// }; + +// class StatQubitTarget : public StationaryQubit { +// public: +// using StationaryQubit::applySingleQubitGateError; +// using StationaryQubit::applyTwoQubitGateError; +// using StationaryQubit::initialize; +// using StationaryQubit::par; +// using StationaryQubit::setSingleQubitGateErrorModel; +// using StationaryQubit::setTwoQubitGateErrorCeilings; +// StatQubitTarget() : StationaryQubit() { +// setComponentType(new TestModuleType("test qubit")); +// provider.setStrategy(std::make_unique()); +// } +// void reset() { +// setFree(true); +// updated_time = SimTime(0); +// no_density_matrix_nullptr_entangled_partner_ok = true; +// } +// void fillParams() { +// setParDouble(this, "emission_success_probability", 0.5); +// setParDouble(this, "memory_X_error_rate", 1.11111111e-7); +// setParDouble(this, "memory_Y_error_rate", 1.11111111e-7); +// setParDouble(this, "memory_Z_error_rate", 1.11111111e-7); +// setParDouble(this, "memory_energy_excitation_rate", 0.000198); +// setParDouble(this, "memory_energy_relaxation_rate", 0.00000198); +// setParDouble(this, "memory_completely_mixed_rate", 0); + +// // No error= 0.4, X error = 0.6, Z error = 0.8, Y error = 1.0 +// setParDouble(this, "Hgate_error_rate", 0.6); +// setParDouble(this, "Hgate_X_error_ratio", 1); +// setParDouble(this, "Hgate_Z_error_ratio", 1); +// setParDouble(this, "Hgate_Y_error_ratio", 1); + +// setParDouble(this, "Xgate_error_rate", 0.6); +// setParDouble(this, "Xgate_X_error_ratio", 1); +// setParDouble(this, "Xgate_Z_error_ratio", 1); +// setParDouble(this, "Xgate_Y_error_ratio", 1); + +// setParDouble(this, "Zgate_error_rate", 0.6); +// setParDouble(this, "Zgate_X_error_ratio", 1); +// setParDouble(this, "Zgate_Z_error_ratio", 1); +// setParDouble(this, "Zgate_Y_error_ratio", 1); + +// // clean = 0.1, +// // IX = 0.2, XI = 0.3, XX = 0.4, +// // IZ = 0.5, ZI = 0.6, ZZ = 0.7, +// // IY = 0.8, IY = 0.9, YY = 1.0 +// setParDouble(this, "CNOTgate_error_rate", 0.9); +// setParDouble(this, "CNOTgate_IX_error_ratio", 1); +// setParDouble(this, "CNOTgate_XI_error_ratio", 1); +// setParDouble(this, "CNOTgate_XX_error_ratio", 1); +// setParDouble(this, "CNOTgate_IZ_error_ratio", 1); +// setParDouble(this, "CNOTgate_ZI_error_ratio", 1); +// setParDouble(this, "CNOTgate_ZZ_error_ratio", 1); +// setParDouble(this, "CNOTgate_IY_error_ratio", 1); +// setParDouble(this, "CNOTgate_YI_error_ratio", 1); +// setParDouble(this, "CNOTgate_YY_error_ratio", 1); + +// setParDouble(this, "X_measurement_error_rate", 1.0 / 2000); +// setParDouble(this, "Y_measurement_error_rate", 1.0 / 2000); +// setParDouble(this, "Z_measurement_error_rate", 1.0 / 2000); + +// setParInt(this, "stationaryQubit_address", 1); +// setParInt(this, "node_address", 1); +// setParInt(this, "qnic_address", 1); +// setParInt(this, "qnic_type", 0); +// setParInt(this, "qnic_index", 0); +// setParDouble(this, "std", 0.5); + +// setParDouble(this, "photon_emitted_at", 0.0); +// setParDouble(this, "last_updated_at", 0.0); +// setParBool(this, "GOD_Xerror", false); +// setParBool(this, "GOD_Zerror", false); +// setParBool(this, "GOD_CMerror", false); +// setParBool(this, "GOD_EXerror", false); +// setParBool(this, "GOD_REerror", false); +// setParBool(this, "isBusy", false); +// setParInt(this, "GOD_entangled_stationaryQubit_address", 0); +// setParInt(this, "GOD_entangled_node_address", 0); +// setParInt(this, "GOD_entangled_qnic_address", 0); +// setParInt(this, "GOD_entangled_qnic_type", 0); +// setParDouble(this, "fidelity", -1.0); +// } +// }; + +// TEST(StatQubitGateErrorTest, SetSingleQubitGateErrorCeilings) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// setParDouble(qubit, "Xgate_error_rate", 0.1); +// setParDouble(qubit, "Xgate_X_error_ratio", 1); +// setParDouble(qubit, "Xgate_Z_error_ratio", 2); +// setParDouble(qubit, "Xgate_Y_error_ratio", 3); +// sim->registerComponent(qubit); +// qubit->setSingleQubitGateErrorModel(qubit->Xgate_error, std::string("Xgate")); +// auto &error_model = qubit->Xgate_error; +// EXPECT_FALSE(std::isnan(error_model.X_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.Y_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.Z_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.X_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.Z_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.Y_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.X_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.Y_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.Z_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.X_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.Z_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.Y_error_ceil)); +// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); +// EXPECT_DOUBLE_EQ(error_model.X_error_rate, 0.1 * 1 / 6); +// EXPECT_DOUBLE_EQ(error_model.Z_error_rate, 0.2 * 1 / 6); +// EXPECT_DOUBLE_EQ(error_model.Y_error_rate, 0.3 * 1 / 6); +// } + +// TEST(StatQubitGateErrorTest, SetSingleQubitGateErrorCeilings_div_by_zero) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// setParDouble(qubit, "Xgate_error_rate", 0.1); +// setParDouble(qubit, "Xgate_X_error_ratio", 0); +// setParDouble(qubit, "Xgate_Z_error_ratio", 0); +// setParDouble(qubit, "Xgate_Y_error_ratio", 0); +// sim->registerComponent(qubit); +// qubit->setSingleQubitGateErrorModel(qubit->Xgate_error, std::string("Xgate")); +// auto &error_model = qubit->Xgate_error; +// EXPECT_FALSE(std::isnan(error_model.X_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.Y_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.Z_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.X_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.Z_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.Y_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.X_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.Y_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.Z_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.X_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.Z_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.Y_error_ceil)); +// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); +// EXPECT_DOUBLE_EQ(error_model.X_error_rate, 0.1 * 1 / 3); +// EXPECT_DOUBLE_EQ(error_model.Z_error_rate, 0.1 * 1 / 3); +// EXPECT_DOUBLE_EQ(error_model.Y_error_rate, 0.1 * 1 / 3); +// } + +// TEST(StatQubitGateErrorTest, SetTwoQubitGateErrorCeilings) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// setParDouble(qubit, "CNOTgate_error_rate", 0.1); +// setParDouble(qubit, "CNOTgate_IX_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_XI_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_XX_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_IZ_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_ZI_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_ZZ_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_IY_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_YI_error_ratio", 1); +// setParDouble(qubit, "CNOTgate_YY_error_ratio", 1); +// sim->registerComponent(qubit); +// qubit->setTwoQubitGateErrorCeilings(qubit->CNOTgate_error, std::string("CNOTgate")); +// auto const &error_model = qubit->CNOTgate_error; +// EXPECT_FALSE(std::isnan(error_model.IX_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.XI_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.XX_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.IZ_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.ZI_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.ZZ_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.IY_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.YI_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.YY_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.XI_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.IX_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.XX_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.ZI_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.IZ_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.ZZ_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.YI_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.IY_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.YY_error_ceil)); + +// EXPECT_FALSE(std::isinf(error_model.XI_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.IX_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.XX_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.ZI_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.IZ_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.ZZ_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.YI_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.IY_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.YY_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.XI_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.IX_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.XX_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.ZI_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.IZ_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.ZZ_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.YI_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.IY_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.YY_error_ceil)); +// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); +// EXPECT_DOUBLE_EQ(error_model.XI_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.IX_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.XX_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.ZI_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.IZ_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.ZZ_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.YI_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.IY_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.YY_error_rate, 0.1 * 1 / 9); +// } + +// TEST(StatQubitGateErrorTest, SetTwoQubitGateErrorCeilings_div_by_zero) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// setParDouble(qubit, "CNOTgate_error_rate", 0.1); +// setParDouble(qubit, "CNOTgate_IX_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_XI_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_XX_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_IZ_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_ZI_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_ZZ_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_IY_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_YI_error_ratio", 0); +// setParDouble(qubit, "CNOTgate_YY_error_ratio", 0); +// sim->registerComponent(qubit); +// qubit->setTwoQubitGateErrorCeilings(qubit->CNOTgate_error, std::string("CNOTgate")); +// auto const &error_model = qubit->CNOTgate_error; +// EXPECT_FALSE(std::isnan(error_model.IX_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.XI_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.XX_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.IZ_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.ZI_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.ZZ_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.IY_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.YI_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.YY_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.XI_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.IX_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.XX_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.ZI_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.IZ_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.ZZ_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.YI_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.IY_error_ceil)); +// EXPECT_FALSE(std::isnan(error_model.YY_error_ceil)); + +// EXPECT_FALSE(std::isinf(error_model.XI_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.IX_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.XX_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.ZI_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.IZ_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.ZZ_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.YI_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.IY_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.YY_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); +// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.XI_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.IX_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.XX_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.ZI_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.IZ_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.ZZ_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.YI_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.IY_error_ceil)); +// EXPECT_FALSE(std::isinf(error_model.YY_error_ceil)); +// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); +// EXPECT_DOUBLE_EQ(error_model.XI_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.IX_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.XX_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.ZI_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.IZ_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.ZZ_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.YI_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.IY_error_rate, 0.1 * 1 / 9); +// EXPECT_DOUBLE_EQ(error_model.YY_error_rate, 0.1 * 1 / 9); +// } +// TEST(StatQubitGateErrorTest, do_nothing_single_qubit_gate) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// setParDouble(qubit, "Xgate_error_rate", 0.0); +// qubit->callInitialize(); +// qubit->reset(); +// qubit->par("GOD_Xerror") = true; +// qubit->par("GOD_Zerror") = true; +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(qubit->par("GOD_REerror")); +// EXPECT_FALSE(qubit->par("GOD_EXerror")); +// sim->registerComponent(qubit); + +// qubit->applySingleQubitGateError(qubit->Xgate_error); + +// EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(qubit->par("GOD_REerror")); +// EXPECT_FALSE(qubit->par("GOD_EXerror")); +// } + +// TEST(StatQubitGateErrorTest, do_nothing_two_qubit_gate) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// auto *qubit2 = new StatQubitTarget{}; +// qubit->fillParams(); +// qubit2->fillParams(); +// setParDouble(qubit, "CNOTgate_error_rate", 0.0); +// qubit->callInitialize(); +// qubit2->callInitialize(); +// qubit->reset(); +// qubit2->reset(); +// qubit->par("GOD_Xerror") = true; +// qubit->par("GOD_Zerror") = true; +// qubit2->par("GOD_Xerror") = true; +// qubit2->par("GOD_Zerror") = true; +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(qubit->par("GOD_REerror")); +// EXPECT_FALSE(qubit->par("GOD_EXerror")); +// EXPECT_TRUE(qubit2->par("GOD_Xerror")); +// EXPECT_TRUE(qubit2->par("GOD_Zerror")); +// EXPECT_FALSE(qubit2->par("GOD_REerror")); +// EXPECT_FALSE(qubit2->par("GOD_EXerror")); +// sim->registerComponent(qubit); +// sim->registerComponent(qubit2); + +// qubit->applyTwoQubitGateError(qubit->CNOTgate_error, qubit2); + +// EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(qubit->par("GOD_REerror")); +// EXPECT_FALSE(qubit->par("GOD_EXerror")); +// EXPECT_TRUE(qubit2->par("GOD_Xerror")); +// EXPECT_TRUE(qubit2->par("GOD_Zerror")); +// EXPECT_FALSE(qubit2->par("GOD_REerror")); +// EXPECT_FALSE(qubit2->par("GOD_EXerror")); +// } + +// TEST(StatQubitGateErrorTest, apply_single_qubit_gate_error) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); + +// qubit->callInitialize(); +// sim->registerComponent(qubit); +// sim->setSimTime(SimTime(1, SIMTIME_US)); +// // No error +// qubit->reset(); +// rng->doubleValue = 0.35; +// qubit->applySingleQubitGateError(qubit->Xgate_error); +// EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); + +// // X error +// qubit->reset(); +// rng->doubleValue = 0.45; +// qubit->applySingleQubitGateError(qubit->Xgate_error); +// EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); + +// // Z error +// qubit->reset(); +// rng->doubleValue = 0.65; +// qubit->applySingleQubitGateError(qubit->Xgate_error); +// EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); + +// // Y error +// qubit->reset(); +// rng->doubleValue = 0.85; +// qubit->applySingleQubitGateError(qubit->Xgate_error); +// EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); +// } + +// TEST(StatQubitGateErrorTest, apply_two_qubit_gate_error) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit1 = new StatQubitTarget{}; +// auto *qubit2 = new StatQubitTarget{}; +// qubit1->fillParams(); +// qubit2->fillParams(); + +// qubit1->callInitialize(); +// qubit2->callInitialize(); +// sim->registerComponent(qubit1); +// sim->registerComponent(qubit2); +// sim->setSimTime(SimTime(1, SIMTIME_US)); + +// // No error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.05; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // IX error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.15; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // XI error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.25; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // XX error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.35; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // IZ error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.45; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // ZI error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.55; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // ZZ error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.65; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // IY error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.75; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // YI error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.85; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); + +// // YY error +// qubit1->reset(); +// qubit2->reset(); +// rng->doubleValue = 0.95; +// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); +// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); +// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); +// } } // namespace diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc index 8695b4dfd..fd29b49cb 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc @@ -94,517 +94,517 @@ class StatQubitTarget : public StationaryQubit { } }; -TEST(StatQubitMeasurementTest, SetMeasurementErrorRate) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - setParDouble(qubit, "x_measurement_error_rate", 0.1); - setParDouble(qubit, "y_measurement_error_rate", 0.2); - setParDouble(qubit, "z_measurement_error_rate", 0.4); - sim->registerComponent(qubit); - qubit->setMeasurementErrorModel(qubit->Measurement_error); - auto &error_model = qubit->Measurement_error; - EXPECT_FALSE(std::isnan(error_model.x_error_rate)); - EXPECT_FALSE(std::isnan(error_model.y_error_rate)); - EXPECT_FALSE(std::isnan(error_model.z_error_rate)); - EXPECT_DOUBLE_EQ(error_model.x_error_rate, 0.1); - EXPECT_DOUBLE_EQ(error_model.y_error_rate, 0.2); - EXPECT_DOUBLE_EQ(error_model.z_error_rate, 0.4); -} - -TEST(StatQubitMeasurementTest, CorrelationMeasureXwithoutError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); -} - -TEST(StatQubitMeasurementTest, CorrelationMeasureXwithError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - - // X error - qubit->addXerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); - - // Y error - qubit->addZerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); - - // Z error - qubit->addXerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); -} - -TEST(StatQubitMeasurementTest, CorrelationMeasureYwithoutError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); -} - -TEST(StatQubitMeasurementTest, CorrelationMeasureYwithError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - - // X error - qubit->addXerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); - - // Y error - qubit->addZerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); - - // Z error - qubit->addXerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); -} - -TEST(StatQubitMeasurementTest, CorrelationMeasureZwithoutError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); -} - -TEST(StatQubitMeasurementTest, CorrelationMeasureZwithError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - - // X error - qubit->addXerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); - - // Y error - qubit->addZerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); - - // Z error - qubit->addXerror(); - rng->doubleValue = 0.5; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); - rng->doubleValue = 1.0 / 3000; - EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); -} - -TEST(StatQubitMeasurementTest, localXMeasurementWithoutError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - auto *another_qubit = new StatQubitTarget{}; - qubit->fillParams(); - another_qubit->fillParams(); - qubit->entangled_partner = another_qubit; - another_qubit->entangled_partner = qubit; - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); -} - -TEST(StatQubitMeasurementTest, localXMeasurementWithError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - auto *another_qubit = new StatQubitTarget{}; - qubit->fillParams(); - another_qubit->fillParams(); - setParDouble(qubit, "x_measurement_error_rate", 0.99); - qubit->entangled_partner = another_qubit; - another_qubit->entangled_partner = qubit; - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_TRUE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); -} - -TEST(StatQubitMeasurementTest, localZMeasurementWithoutError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - auto *another_qubit = new StatQubitTarget{}; - qubit->fillParams(); - another_qubit->fillParams(); - qubit->entangled_partner = another_qubit; - another_qubit->entangled_partner = qubit; - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); -} - -TEST(StatQubitMeasurementTest, localZMeasurementWithError) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - auto *another_qubit = new StatQubitTarget{}; - qubit->fillParams(); - another_qubit->fillParams(); - setParDouble(qubit, "z_measurement_error_rate", 0.99); - qubit->entangled_partner = another_qubit; - another_qubit->entangled_partner = qubit; - qubit->setMeasurementErrorModel(qubit->Measurement_error); - sim->registerComponent(qubit); - - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.7; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_TRUE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); - - qubit->reset(); - another_qubit->reset(); - qubit->addZerror(); - qubit->addXerror(); - rng->doubleValue = 0.3; - EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(another_qubit->god_err.has_x_error); - EXPECT_FALSE(another_qubit->god_err.has_z_error); -} +// TEST(StatQubitMeasurementTest, SetMeasurementErrorRate) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// setParDouble(qubit, "X_measurement_error_rate", 0.1); +// setParDouble(qubit, "Y_measurement_error_rate", 0.2); +// setParDouble(qubit, "Z_measurement_error_rate", 0.4); +// sim->registerComponent(qubit); +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// auto &error_model = qubit->Measurement_error; +// EXPECT_FALSE(std::isnan(error_model.x_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.y_error_rate)); +// EXPECT_FALSE(std::isnan(error_model.z_error_rate)); +// EXPECT_DOUBLE_EQ(error_model.x_error_rate, 0.1); +// EXPECT_DOUBLE_EQ(error_model.y_error_rate, 0.2); +// EXPECT_DOUBLE_EQ(error_model.z_error_rate, 0.4); +// } + +// TEST(StatQubitMeasurementTest, CorrelationMeasureXwithoutError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); +// } + +// TEST(StatQubitMeasurementTest, CorrelationMeasureXwithError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); + +// // X error +// qubit->addXerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); + +// // Y error +// qubit->addZerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); + +// // Z error +// qubit->addXerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); +// } + +// TEST(StatQubitMeasurementTest, CorrelationMeasureYwithoutError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); +// } + +// TEST(StatQubitMeasurementTest, CorrelationMeasureYwithError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); + +// // X error +// qubit->addXerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); + +// // Y error +// qubit->addZerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); + +// // Z error +// qubit->addXerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); +// } + +// TEST(StatQubitMeasurementTest, CorrelationMeasureZwithoutError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); +// } + +// TEST(StatQubitMeasurementTest, CorrelationMeasureZwithError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); + +// // X error +// qubit->addXerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); + +// // Y error +// qubit->addZerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); + +// // Z error +// qubit->addXerror(); +// rng->doubleValue = 0.5; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); +// rng->doubleValue = 1.0 / 3000; +// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); +// } + +// TEST(StatQubitMeasurementTest, localXMeasurementWithoutError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// auto *another_qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// another_qubit->fillParams(); +// qubit->entangled_partner = another_qubit; +// another_qubit->entangled_partner = qubit; +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); + +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); +// } + +// TEST(StatQubitMeasurementTest, localXMeasurementWithError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// auto *another_qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// another_qubit->fillParams(); +// setParDouble(qubit, "X_measurement_error_rate", 0.99); +// qubit->entangled_partner = another_qubit; +// another_qubit->entangled_partner = qubit; +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); + +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); +// } + +// TEST(StatQubitMeasurementTest, localZMeasurementWithoutError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// auto *another_qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// another_qubit->fillParams(); +// qubit->entangled_partner = another_qubit; +// another_qubit->entangled_partner = qubit; +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); + +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); +// } + +// TEST(StatQubitMeasurementTest, localZMeasurementWithError) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// auto *another_qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// another_qubit->fillParams(); +// setParDouble(qubit, "Z_measurement_error_rate", 0.99); +// qubit->entangled_partner = another_qubit; +// another_qubit->entangled_partner = qubit; +// qubit->setMeasurementErrorModel(qubit->Measurement_error); +// sim->registerComponent(qubit); + +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.7; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); + +// qubit->reset(); +// another_qubit->reset(); +// qubit->addZerror(); +// qubit->addXerror(); +// rng->doubleValue = 0.3; +// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); +// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); +// } } // end namespace diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc index 0cde3292b..026fbfd09 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc @@ -9,13 +9,13 @@ using namespace quisp::modules; using namespace quisp::modules::common; using namespace quisp_test; namespace { -class Strategy : public TestComponentProviderStrategy { - public: - Strategy() : backend(new MockQuantumBackend()) {} - ~Strategy() {} - IQuantumBackend *getQuantumBackend() override { return backend; } - MockQuantumBackend *backend; -}; +// class Strategy : public TestComponentProviderStrategy { +// public: +// Strategy() : backend(new MockQuantumBackend()) {} +// ~Strategy() {} +// IQuantumBackend *getQuantumBackend() override { return backend; } +// MockQuantumBackend *backend; +// }; class StatQubitTarget : public StationaryQubit { public: @@ -34,49 +34,63 @@ class StatQubitTarget : public StationaryQubit { void fillParams() { // see networks/omnetpp.ini setParDouble(this, "emission_success_probability", 0.5); - setParDouble(this, "memory_x_error_rate", 1.11111111e-7); - setParDouble(this, "memory_y_error_rate", 1.11111111e-7); - setParDouble(this, "memory_z_error_rate", 1.11111111e-7); + setParDouble(this, "memory_X_error_rate", 1.11111111e-7); + setParDouble(this, "memory_Y_error_rate", 1.11111111e-7); + setParDouble(this, "memory_Z_error_rate", 1.11111111e-7); setParDouble(this, "memory_energy_excitation_rate", 0.000198); setParDouble(this, "memory_energy_relaxation_rate", 0.00000198); setParDouble(this, "memory_completely_mixed_rate", 0); - setParDouble(this, "h_gate_error_rate", 1. / 2000); - setParDouble(this, "h_gate_x_error_ratio", 0); - setParDouble(this, "h_gate_z_error_ratio", 0); - setParDouble(this, "h_gate_y_error_ratio", 0); - - setParDouble(this, "x_gate_error_rate", 1. / 2000); - setParDouble(this, "x_gate_x_error_ratio", 0); - setParDouble(this, "x_gate_z_error_ratio", 0); - setParDouble(this, "x_gate_y_error_ratio", 0); - - setParDouble(this, "z_gate_error_rate", 1. / 2000); - setParDouble(this, "z_gate_x_error_ratio", 0); - setParDouble(this, "z_gate_z_error_ratio", 0); - setParDouble(this, "z_gate_y_error_ratio", 0); - - setParDouble(this, "cnot_gate_error_rate", 1. / 2000); - setParDouble(this, "cnot_gate_ix_error_ratio", 1); - setParDouble(this, "cnot_gate_xi_error_ratio", 1); - setParDouble(this, "cnot_gate_xx_error_ratio", 1); - setParDouble(this, "cnot_gate_iz_error_ratio", 1); - setParDouble(this, "cnot_gate_zi_error_ratio", 1); - setParDouble(this, "cnot_gate_zz_error_ratio", 1); - setParDouble(this, "cnot_gate_iy_error_ratio", 1); - setParDouble(this, "cnot_gate_yi_error_ratio", 1); - setParDouble(this, "cnot_gate_yy_error_ratio", 1); - - setParDouble(this, "x_measurement_error_rate", 1. / 2000); - setParDouble(this, "y_measurement_error_rate", 1. / 2000); - setParDouble(this, "z_measurement_error_rate", 1. / 2000); - - setParInt(this, "stationary_qubit_address", 1); + setParDouble(this, "Hgate_error_rate", 1. / 2000); + setParDouble(this, "Hgate_X_error_ratio", 0); + setParDouble(this, "Hgate_Z_error_ratio", 0); + setParDouble(this, "Hgate_Y_error_ratio", 0); + + setParDouble(this, "Xgate_error_rate", 1. / 2000); + setParDouble(this, "Xgate_X_error_ratio", 0); + setParDouble(this, "Xgate_Z_error_ratio", 0); + setParDouble(this, "Xgate_Y_error_ratio", 0); + + setParDouble(this, "Zgate_error_rate", 1. / 2000); + setParDouble(this, "Zgate_X_error_ratio", 0); + setParDouble(this, "Zgate_Z_error_ratio", 0); + setParDouble(this, "Zgate_Y_error_ratio", 0); + + setParDouble(this, "CNOTgate_error_rate", 1. / 2000); + setParDouble(this, "CNOTgate_IX_error_ratio", 1); + setParDouble(this, "CNOTgate_XI_error_ratio", 1); + setParDouble(this, "CNOTgate_XX_error_ratio", 1); + setParDouble(this, "CNOTgate_IZ_error_ratio", 1); + setParDouble(this, "CNOTgate_ZI_error_ratio", 1); + setParDouble(this, "CNOTgate_ZZ_error_ratio", 1); + setParDouble(this, "CNOTgate_IY_error_ratio", 1); + setParDouble(this, "CNOTgate_YI_error_ratio", 1); + setParDouble(this, "CNOTgate_YY_error_ratio", 1); + + setParDouble(this, "X_measurement_error_rate", 1. / 2000); + setParDouble(this, "Y_measurement_error_rate", 1. / 2000); + setParDouble(this, "Z_measurement_error_rate", 1. / 2000); + + setParInt(this, "stationaryQubit_address", 1); setParInt(this, "node_address", 1); setParInt(this, "qnic_address", 1); setParInt(this, "qnic_type", 0); setParInt(this, "qnic_index", 0); - setParDouble(this, "emission_jittering_standard_deviation", 0.5); + setParDouble(this, "std", 0.5); + + setParDouble(this, "photon_emitted_at", 0.0); + setParDouble(this, "last_updated_at", 0.0); + setParBool(this, "GOD_Xerror", false); + setParBool(this, "GOD_Zerror", false); + setParBool(this, "GOD_CMerror", false); + setParBool(this, "GOD_EXerror", false); + setParBool(this, "GOD_REerror", false); + setParBool(this, "isBusy", false); + setParInt(this, "GOD_entangled_stationaryQubit_address", 0); + setParInt(this, "GOD_entangled_node_address", 0); + setParInt(this, "GOD_entangled_qnic_address", 0); + setParInt(this, "GOD_entangled_qnic_type", 0); + setParDouble(this, "fidelity", -1.0); } }; @@ -84,37 +98,35 @@ TEST(StatQubitMemoryErrorTest, do_nothing) { auto *sim = prepareSimulation(); auto *qubit = new StatQubitTarget{}; qubit->fillParams(); - sim->registerComponent(qubit); - qubit->callInitialize(); qubit->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - - // if current time and updated_time are same, do nothing - EXPECT_EQ(qubit->updated_time, SimTime(0)); - sim->setSimTime(SimTime(0, SIMTIME_US)); - qubit->applyMemoryError(); + qubit->par("GOD_Xerror") = true; + qubit->par("GOD_Zerror") = true; + EXPECT_TRUE(qubit->par("GOD_Xerror")); + EXPECT_TRUE(qubit->par("GOD_Zerror")); + EXPECT_FALSE(qubit->par("GOD_REerror")); + EXPECT_FALSE(qubit->par("GOD_EXerror")); + sim->registerComponent(qubit); + +// // if current time and updated_time are same, do nothing +// EXPECT_EQ(qubit->updated_time, SimTime(0)); +// sim->setSimTime(SimTime(0, SIMTIME_US)); +// qubit->applyMemoryError(); EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); + EXPECT_TRUE(qubit->par("GOD_Xerror")); + EXPECT_TRUE(qubit->par("GOD_Zerror")); + EXPECT_FALSE(qubit->par("GOD_REerror")); + EXPECT_FALSE(qubit->par("GOD_EXerror")); } TEST(StatQubitMemoryErrorTest, update_timestamp) { auto *sim = prepareSimulation(); auto *qubit = new StatQubitTarget{}; qubit->fillParams(); - sim->registerComponent(qubit); - qubit->callInitialize(); qubit->reset(); EXPECT_EQ(qubit->updated_time, SimTime(0)); + sim->registerComponent(qubit); sim->setSimTime(SimTime(1, SIMTIME_US)); qubit->applyMemoryError(); EXPECT_EQ(qubit->updated_time, SimTime(1, SIMTIME_US)); @@ -129,69 +141,68 @@ TEST(StatQubitMemoryErrorTest, apply_memory_error_no_error) { // this means take 1st row of MemoryTransitionMatrix // ceiled values should be: // No error= 0.5, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_x_error_rate", .1); - setParDouble(qubit, "memory_y_error_rate", .1); - setParDouble(qubit, "memory_z_error_rate", .1); + setParDouble(qubit, "memory_X_error_rate", .1); + setParDouble(qubit, "memory_Y_error_rate", .1); + setParDouble(qubit, "memory_Z_error_rate", .1); setParDouble(qubit, "memory_energy_excitation_rate", .1); setParDouble(qubit, "memory_energy_relaxation_rate", .1); setParDouble(qubit, "memory_completely_mixed_rate", 0); - sim->registerComponent(qubit); - qubit->callInitialize(); + sim->registerComponent(qubit); sim->setSimTime(SimTime(1, SIMTIME_US)); // X error qubit->reset(); rng->doubleValue = 0.55; qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Z error rng->doubleValue = 0.65; qubit->reset(); qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Y error rng->doubleValue = 0.75; qubit->reset(); qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Excitation error rng->doubleValue = 0.85; qubit->reset(); qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Relaxation error rng->doubleValue = 0.95; qubit->reset(); qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); } -TEST(StatQubitMemoryErrorTest, apply_memory_error_x_error) { +TEST(StatQubitMemoryErrorTest, apply_memory_error_X_error) { auto *sim = prepareSimulation(); auto *rng = useTestRNG(); auto *qubit = new StatQubitTarget{}; @@ -201,73 +212,73 @@ TEST(StatQubitMemoryErrorTest, apply_memory_error_x_error) { // this means take 2nd row of MemoryTransitionMatrix // ceiled values should be: // No error= 0.1, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_x_error_rate", .1); - setParDouble(qubit, "memory_y_error_rate", .1); - setParDouble(qubit, "memory_z_error_rate", .1); + setParDouble(qubit, "memory_X_error_rate", .1); + setParDouble(qubit, "memory_Y_error_rate", .1); + setParDouble(qubit, "memory_Z_error_rate", .1); setParDouble(qubit, "memory_energy_excitation_rate", .1); setParDouble(qubit, "memory_energy_relaxation_rate", .1); setParDouble(qubit, "memory_completely_mixed_rate", 0); - sim->registerComponent(qubit); qubit->callInitialize(); + sim->registerComponent(qubit); sim->setSimTime(SimTime(1, SIMTIME_US)); // X error qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; rng->doubleValue = 0.55; qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Z error rng->doubleValue = 0.65; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Y error rng->doubleValue = 0.75; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Excitation error rng->doubleValue = 0.85; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Relaxation error rng->doubleValue = 0.95; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); } -TEST(StatQubitMemoryErrorTest, apply_memory_error_z_error) { +TEST(StatQubitMemoryErrorTest, apply_memory_error_Z_error) { auto *sim = prepareSimulation(); auto *rng = useTestRNG(); auto *qubit = new StatQubitTarget{}; @@ -277,73 +288,73 @@ TEST(StatQubitMemoryErrorTest, apply_memory_error_z_error) { // this means take 3rd row of MemoryTransitionMatrix // ceiled values should be: // No error= 0.1, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_x_error_rate", .1); - setParDouble(qubit, "memory_y_error_rate", .1); - setParDouble(qubit, "memory_z_error_rate", .1); + setParDouble(qubit, "memory_X_error_rate", .1); + setParDouble(qubit, "memory_Y_error_rate", .1); + setParDouble(qubit, "memory_Z_error_rate", .1); setParDouble(qubit, "memory_energy_excitation_rate", .1); setParDouble(qubit, "memory_energy_relaxation_rate", .1); setParDouble(qubit, "memory_completely_mixed_rate", 0); - sim->registerComponent(qubit); qubit->callInitialize(); + sim->registerComponent(qubit); sim->setSimTime(SimTime(1, SIMTIME_US)); // X error qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; rng->doubleValue = 0.55; qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Z error rng->doubleValue = 0.65; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Y error rng->doubleValue = 0.75; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Excitation error rng->doubleValue = 0.85; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Relaxation error rng->doubleValue = 0.95; qubit->reset(); - qubit->god_err.has_x_error = true; + qubit->par("GOD_Xerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); } -TEST(StatQubitMemoryErrorTest, apply_memory_error_y_error) { +TEST(StatQubitMemoryErrorTest, apply_memory_error_Y_error) { auto *sim = prepareSimulation(); auto *rng = useTestRNG(); auto *qubit = new StatQubitTarget{}; @@ -353,194 +364,194 @@ TEST(StatQubitMemoryErrorTest, apply_memory_error_y_error) { // this means take 4th row of MemoryTransitionMatrix // ceiled values should be: // No error= 0.1, X error = 0.2, Z error = 0.3, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_x_error_rate", .1); - setParDouble(qubit, "memory_y_error_rate", .1); - setParDouble(qubit, "memory_z_error_rate", .1); + setParDouble(qubit, "memory_X_error_rate", .1); + setParDouble(qubit, "memory_Y_error_rate", .1); + setParDouble(qubit, "memory_Z_error_rate", .1); setParDouble(qubit, "memory_energy_excitation_rate", .1); setParDouble(qubit, "memory_energy_relaxation_rate", .1); setParDouble(qubit, "memory_completely_mixed_rate", 0); - sim->registerComponent(qubit); qubit->callInitialize(); + sim->registerComponent(qubit); sim->setSimTime(SimTime(1, SIMTIME_US)); // X error qubit->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; + qubit->par("GOD_Xerror") = true; + qubit->par("GOD_Zerror") = true; rng->doubleValue = 0.15; qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Z error rng->doubleValue = 0.25; qubit->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; + qubit->par("GOD_Xerror") = true; + qubit->par("GOD_Zerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Y error rng->doubleValue = 0.5; qubit->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; + qubit->par("GOD_Xerror") = true; + qubit->par("GOD_Zerror") = true; qubit->applyMemoryError(); - EXPECT_TRUE(qubit->god_err.has_x_error); - EXPECT_TRUE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Excitation error rng->doubleValue = 0.85; qubit->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; + qubit->par("GOD_Xerror") = true; + qubit->par("GOD_Zerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Relaxation error rng->doubleValue = 0.95; qubit->reset(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; + qubit->par("GOD_Xerror") = true; + qubit->par("GOD_Zerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); } -TEST(StatQubitMemoryErrorTest, apply_memory_error_excitation_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); +// TEST(StatQubitMemoryErrorTest, apply_memory_error_excitation_error) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); // Initial_condition << 0, 0, 0, 0, 1, 0, 0; // this means take 5th row of MemoryTransitionMatrix // ceiled values should be: // No error= 0.1, X error = 0.2, Z error = 0.3, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_x_error_rate", .1); - setParDouble(qubit, "memory_y_error_rate", .1); - setParDouble(qubit, "memory_z_error_rate", .1); + setParDouble(qubit, "memory_X_error_rate", .1); + setParDouble(qubit, "memory_Y_error_rate", .1); + setParDouble(qubit, "memory_Z_error_rate", .1); setParDouble(qubit, "memory_energy_excitation_rate", .1); setParDouble(qubit, "memory_energy_relaxation_rate", .1); setParDouble(qubit, "memory_completely_mixed_rate", 0); - sim->registerComponent(qubit); qubit->callInitialize(); + sim->registerComponent(qubit); sim->setSimTime(SimTime(1, SIMTIME_US)); // X error qubit->reset(); - qubit->god_err.has_excitation_error = true; + qubit->par("GOD_EXerror") = true; rng->doubleValue = 0.15; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Z error rng->doubleValue = 0.25; qubit->reset(); - qubit->god_err.has_excitation_error = true; + qubit->par("GOD_EXerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Y error rng->doubleValue = 0.5; qubit->reset(); - qubit->god_err.has_excitation_error = true; + qubit->par("GOD_EXerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Excitation error rng->doubleValue = 0.85; qubit->reset(); - qubit->god_err.has_excitation_error = true; + qubit->par("GOD_EXerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Relaxation error rng->doubleValue = 0.95; qubit->reset(); - qubit->god_err.has_excitation_error = true; + qubit->par("GOD_EXerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); } -TEST(StatQubitMemoryErrorTest, apply_memory_error_relaxation_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); +// TEST(StatQubitMemoryErrorTest, apply_memory_error_relaxation_error) { +// auto *sim = prepareSimulation(); +// auto *rng = useTestRNG(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); // Initial_condition << 0, 0, 0, 0, 0, 1, 0; // this means take 6th row of MemoryTransitionMatrix // ceiled values should be: // No error= 0, X error = 0, Z error = 0, Y error = 0, Excitation = 0.1, Relaxation = 1.0 - setParDouble(qubit, "memory_x_error_rate", .1); - setParDouble(qubit, "memory_y_error_rate", .1); - setParDouble(qubit, "memory_z_error_rate", .1); + setParDouble(qubit, "memory_X_error_rate", .1); + setParDouble(qubit, "memory_Y_error_rate", .1); + setParDouble(qubit, "memory_Z_error_rate", .1); setParDouble(qubit, "memory_energy_excitation_rate", .1); setParDouble(qubit, "memory_energy_relaxation_rate", .1); setParDouble(qubit, "memory_completely_mixed_rate", 0); - sim->registerComponent(qubit); qubit->callInitialize(); + sim->registerComponent(qubit); sim->setSimTime(SimTime(1, SIMTIME_US)); // Excitation error rng->doubleValue = 0.05; qubit->reset(); - qubit->god_err.has_relaxation_error = true; + qubit->par("GOD_REerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_TRUE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // Relaxation error rng->doubleValue = 0.95; qubit->reset(); - qubit->god_err.has_relaxation_error = true; + qubit->par("GOD_REerror") = true; qubit->applyMemoryError(); - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_TRUE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); + EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); + EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); + EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); } } // namespace diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 0c61d86ea..ae70e7fc2 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -84,200 +84,200 @@ class StatQubitTarget : public StationaryQubit { } }; -TEST(StatQubitTest, initialize_memory_transition_matrix) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - setParDouble(qubit, "memory_x_error_rate", .011); - setParDouble(qubit, "memory_y_error_rate", .012); - setParDouble(qubit, "memory_z_error_rate", .013); - setParDouble(qubit, "memory_energy_excitation_rate", .014); - setParDouble(qubit, "memory_energy_relaxation_rate", .015); - setParDouble(qubit, "memory_completely_mixed_rate", 0); - sim->registerComponent(qubit); - qubit->callInitialize(); - - auto mat = qubit->Memory_Transition_matrix; - - // each element means: "Clean Xerror Zerror Yerror Excited Relaxed Mixed" - Eigen::RowVectorXd row0(7); - double sigma = .011 + .013 + .012 + .014 + .015; - row0 << 1 - sigma, .011, .013, .012, .014, .015, .0; - ASSERT_EQ(mat.row(0), row0); - - Eigen::RowVectorXd row1(7); - row1 << .011, 1 - sigma, .012, .013, .014, .015, .0; - ASSERT_EQ(mat.row(1), row1); - - Eigen::RowVectorXd row2(7); - row2 << .013, .012, 1 - sigma, .011, .014, .015, .0; - ASSERT_EQ(mat.row(2), row2); - - Eigen::RowVectorXd row3(7); - row3 << .012, .013, .011, 1 - sigma, .014, .015, .0; - ASSERT_EQ(mat.row(3), row3); - - Eigen::RowVectorXd row4(7); - row4 << 0, 0, 0, 0, 1 - .015, .015, .0; - ASSERT_EQ(mat.row(4), row4); - - Eigen::RowVectorXd row5(7); - row5 << 0, 0, 0, 0, .014, 1 - .014, .0; - ASSERT_EQ(mat.row(5), row5); - - Eigen::RowVectorXd row6(7); - row6 << 0, 0, 0, 0, .014, .015, 1 - (.014 + .015); - ASSERT_EQ(mat.row(6), row6); -} - -TEST(StatQubitTest, setFree) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - sim->registerComponent(qubit); - qubit->fillParams(); - qubit->callInitialize(); - qubit->god_err.has_x_error = true; - qubit->god_err.has_z_error = true; - qubit->god_err.has_excitation_error = true; - qubit->god_err.has_relaxation_error = true; - qubit->god_err.has_completely_mixed_error = true; - - qubit->setFree(true); - EXPECT_EQ(qubit->updated_time, simTime()); - auto last_updated_at = qubit->updated_time; - sim->setSimTime(10); - EXPECT_EQ(qubit->updated_time, last_updated_at); - qubit->setFree(true); - EXPECT_EQ(qubit->updated_time, simTime()); - - // check the qubit reset properly - EXPECT_FALSE(qubit->god_err.has_x_error); - EXPECT_FALSE(qubit->god_err.has_z_error); - EXPECT_FALSE(qubit->god_err.has_excitation_error); - EXPECT_FALSE(qubit->god_err.has_relaxation_error); - EXPECT_FALSE(qubit->god_err.has_completely_mixed_error); -} - -TEST(StatQubitTest, setFreeUpdatesTime) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - sim->registerComponent(qubit); - qubit->fillParams(); - qubit->callInitialize(); - - qubit->setFree(true); - EXPECT_EQ(qubit->updated_time, simTime()); - - auto last_updated_at = qubit->updated_time; - sim->setSimTime(10); - EXPECT_EQ(qubit->updated_time, last_updated_at); - - qubit->setFree(true); - EXPECT_EQ(qubit->updated_time, simTime()); -} - -TEST(StatQubitTest, addXError) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - sim->registerComponent(qubit); - EXPECT_FALSE(qubit->god_err.has_x_error); - qubit->addXerror(); - EXPECT_TRUE(qubit->god_err.has_x_error); - qubit->addXerror(); - EXPECT_FALSE(qubit->god_err.has_x_error); -} - -TEST(StatQubitTest, addZError) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - sim->registerComponent(qubit); - EXPECT_FALSE(qubit->god_err.has_z_error); - qubit->addZerror(); - EXPECT_TRUE(qubit->god_err.has_z_error); - qubit->addZerror(); - EXPECT_FALSE(qubit->god_err.has_z_error); -} - -TEST(StatQubitTest, getErrorMatrixTest) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - sim->registerComponent(qubit); - qubit->callInitialize(); - Matrix2cd err; - - err = qubit->getErrorMatrix(qubit); - EXPECT_EQ(Matrix2cd::Identity(), err); - - Matrix2cd Z(2, 2); - Z << 1, 0, 0, -1; - qubit->addZerror(); - err = qubit->getErrorMatrix(qubit); - EXPECT_EQ(Z, err); - qubit->setFree(true); - - Matrix2cd X(2, 2); - X << 0, 1, 1, 0; - qubit->addXerror(); - err = qubit->getErrorMatrix(qubit); - EXPECT_EQ(X, err); - qubit->setFree(true); - - Matrix2cd Y(2, 2); - Y << 0, Complex(0, -1), Complex(0, 1), 0; - qubit->addXerror(); - qubit->addZerror(); - err = qubit->getErrorMatrix(qubit); - EXPECT_EQ(Y, err); - qubit->setFree(true); -} - -TEST(StatQubitTest, getQuantumState) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - auto *partner_qubit = new StatQubitTarget{}; - sim->registerComponent(qubit); - sim->registerComponent(partner_qubit); - qubit->fillParams(); - qubit->callInitialize(); - partner_qubit->fillParams(); - partner_qubit->callInitialize(); - qubit->setEntangledPartnerInfo(partner_qubit); - - quantum_state state; - - state = qubit->getQuantumState(); - Vector4cd state_vector(4); - state_vector << 1 / sqrt(2), 0, 0, 1 / sqrt(2); - Matrix4cd dm(4, 4); - dm = state_vector * state_vector.adjoint(); - EXPECT_EQ(dm, state.state_in_density_matrix); - EXPECT_EQ(state_vector, state.state_in_ket); - - qubit->addXerror(); - state = qubit->getQuantumState(); - state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; - dm = state_vector * state_vector.adjoint(); - EXPECT_EQ(dm, state.state_in_density_matrix); - EXPECT_EQ(state_vector, state.state_in_ket); - qubit->addXerror(); - - partner_qubit->addXerror(); - state = qubit->getQuantumState(); - state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; - dm = state_vector * state_vector.adjoint(); - EXPECT_EQ(dm, state.state_in_density_matrix); - EXPECT_EQ(state_vector, state.state_in_ket); - partner_qubit->addXerror(); - - qubit->addZerror(); - state = qubit->getQuantumState(); - state_vector << 1 / sqrt(2), 0, 0, -1 / sqrt(2); - dm = state_vector * state_vector.adjoint(); - EXPECT_EQ(dm, state.state_in_density_matrix); - EXPECT_EQ(state_vector, state.state_in_ket); - qubit->addZerror(); -} +// TEST(StatQubitTest, initialize_memory_transition_matrix) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// setParDouble(qubit, "memory_X_error_rate", .011); +// setParDouble(qubit, "memory_Y_error_rate", .012); +// setParDouble(qubit, "memory_Z_error_rate", .013); +// setParDouble(qubit, "memory_energy_excitation_rate", .014); +// setParDouble(qubit, "memory_energy_relaxation_rate", .015); +// setParDouble(qubit, "memory_completely_mixed_rate", 0); +// sim->registerComponent(qubit); +// qubit->callInitialize(); + +// auto mat = qubit->Memory_Transition_matrix; + +// // each element means: "Clean Xerror Zerror Yerror Excited Relaxed Mixed" +// Eigen::RowVectorXd row0(7); +// double sigma = .011 + .013 + .012 + .014 + .015; +// row0 << 1 - sigma, .011, .013, .012, .014, .015, .0; +// ASSERT_EQ(mat.row(0), row0); + +// Eigen::RowVectorXd row1(7); +// row1 << .011, 1 - sigma, .012, .013, .014, .015, .0; +// ASSERT_EQ(mat.row(1), row1); + +// Eigen::RowVectorXd row2(7); +// row2 << .013, .012, 1 - sigma, .011, .014, .015, .0; +// ASSERT_EQ(mat.row(2), row2); + +// Eigen::RowVectorXd row3(7); +// row3 << .012, .013, .011, 1 - sigma, .014, .015, .0; +// ASSERT_EQ(mat.row(3), row3); + +// Eigen::RowVectorXd row4(7); +// row4 << 0, 0, 0, 0, 1 - .015, .015, .0; +// ASSERT_EQ(mat.row(4), row4); + +// Eigen::RowVectorXd row5(7); +// row5 << 0, 0, 0, 0, .014, 1 - .014, .0; +// ASSERT_EQ(mat.row(5), row5); + +// Eigen::RowVectorXd row6(7); +// row6 << 0, 0, 0, 0, .014, .015, 1 - (.014 + .015); +// ASSERT_EQ(mat.row(6), row6); +// } + +// TEST(StatQubitTest, setFree) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// sim->registerComponent(qubit); +// qubit->fillParams(); +// qubit->callInitialize(); +// qubit->par("GOD_Xerror") = true; +// qubit->par("GOD_Zerror") = true; +// qubit->par("GOD_EXerror") = true; +// qubit->par("GOD_REerror") = true; +// qubit->par("GOD_CMerror") = true; + +// qubit->setFree(true); +// EXPECT_EQ(qubit->updated_time, simTime()); +// auto last_updated_at = qubit->updated_time; +// sim->setSimTime(10); +// EXPECT_EQ(qubit->updated_time, last_updated_at); +// qubit->setFree(true); +// EXPECT_EQ(qubit->updated_time, simTime()); + +// // check the qubit reset properly +// EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); +// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); +// } + +// TEST(StatQubitTest, setFreeUpdatesTime) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// sim->registerComponent(qubit); +// qubit->fillParams(); +// qubit->callInitialize(); + +// qubit->setFree(true); +// EXPECT_EQ(qubit->updated_time, simTime()); + +// auto last_updated_at = qubit->updated_time; +// sim->setSimTime(10); +// EXPECT_EQ(qubit->updated_time, last_updated_at); + +// qubit->setFree(true); +// EXPECT_EQ(qubit->updated_time, simTime()); +// } + +// TEST(StatQubitTest, addXError) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// sim->registerComponent(qubit); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// qubit->addXerror(); +// EXPECT_TRUE(qubit->par("GOD_Xerror")); +// qubit->addXerror(); +// EXPECT_FALSE(qubit->par("GOD_Xerror")); +// } + +// TEST(StatQubitTest, addZError) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// sim->registerComponent(qubit); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// qubit->addZerror(); +// EXPECT_TRUE(qubit->par("GOD_Zerror")); +// qubit->addZerror(); +// EXPECT_FALSE(qubit->par("GOD_Zerror")); +// } + +// TEST(StatQubitTest, getErrorMatrixTest) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// qubit->fillParams(); +// sim->registerComponent(qubit); +// qubit->callInitialize(); +// Matrix2cd err; + +// err = qubit->getErrorMatrix(qubit); +// EXPECT_EQ(Matrix2cd::Identity(), err); + +// Matrix2cd Z(2, 2); +// Z << 1, 0, 0, -1; +// qubit->addZerror(); +// err = qubit->getErrorMatrix(qubit); +// EXPECT_EQ(Z, err); +// qubit->setFree(true); + +// Matrix2cd X(2, 2); +// X << 0, 1, 1, 0; +// qubit->addXerror(); +// err = qubit->getErrorMatrix(qubit); +// EXPECT_EQ(X, err); +// qubit->setFree(true); + +// Matrix2cd Y(2, 2); +// Y << 0, Complex(0, -1), Complex(0, 1), 0; +// qubit->addXerror(); +// qubit->addZerror(); +// err = qubit->getErrorMatrix(qubit); +// EXPECT_EQ(Y, err); +// qubit->setFree(true); +// } + +// TEST(StatQubitTest, getQuantumState) { +// auto *sim = prepareSimulation(); +// auto *qubit = new StatQubitTarget{}; +// auto *partner_qubit = new StatQubitTarget{}; +// sim->registerComponent(qubit); +// sim->registerComponent(partner_qubit); +// qubit->fillParams(); +// qubit->callInitialize(); +// partner_qubit->fillParams(); +// partner_qubit->callInitialize(); +// qubit->setEntangledPartnerInfo(partner_qubit); + +// quantum_state state; + +// state = qubit->getQuantumState(); +// Vector4cd state_vector(4); +// state_vector << 1 / sqrt(2), 0, 0, 1 / sqrt(2); +// Matrix4cd dm(4, 4); +// dm = state_vector * state_vector.adjoint(); +// EXPECT_EQ(dm, state.state_in_density_matrix); +// EXPECT_EQ(state_vector, state.state_in_ket); + +// qubit->addXerror(); +// state = qubit->getQuantumState(); +// state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; +// dm = state_vector * state_vector.adjoint(); +// EXPECT_EQ(dm, state.state_in_density_matrix); +// EXPECT_EQ(state_vector, state.state_in_ket); +// qubit->addXerror(); + +// partner_qubit->addXerror(); +// state = qubit->getQuantumState(); +// state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; +// dm = state_vector * state_vector.adjoint(); +// EXPECT_EQ(dm, state.state_in_density_matrix); +// EXPECT_EQ(state_vector, state.state_in_ket); +// partner_qubit->addXerror(); + +// qubit->addZerror(); +// state = qubit->getQuantumState(); +// state_vector << 1 / sqrt(2), 0, 0, -1 / sqrt(2); +// dm = state_vector * state_vector.adjoint(); +// EXPECT_EQ(dm, state.state_in_density_matrix); +// EXPECT_EQ(state_vector, state.state_in_ket); +// qubit->addZerror(); +// } } // namespace diff --git a/quisp/test_utils/mock_modules/MockQubit.h b/quisp/test_utils/mock_modules/MockQubit.h index ce10a33cc..5a83e5029 100644 --- a/quisp/test_utils/mock_modules/MockQubit.h +++ b/quisp/test_utils/mock_modules/MockQubit.h @@ -30,8 +30,6 @@ class MockQubit : public IStationaryQubit { MOCK_METHOD(quisp::types::EigenvalueResult, localMeasureZ, (), (override)); MOCK_METHOD(bool, Xpurify, (IStationaryQubit *), (override)); MOCK_METHOD(bool, Zpurify, (IStationaryQubit *), (override)); - MOCK_METHOD(void, addXerror, (), (override)); - MOCK_METHOD(void, addZerror, (), (override)); MOCK_METHOD(void, Z_gate, (), (override)); MOCK_METHOD(void, X_gate, (), (override)); MOCK_METHOD(void, Hadamard_gate, (), (override)); @@ -39,14 +37,9 @@ class MockQubit : public IStationaryQubit { MOCK_METHOD(void, Lock, (unsigned long rs_id, int rule_id, int action_id), (override)); MOCK_METHOD(void, Unlock, (), (override)); MOCK_METHOD(bool, isLocked, (), (override)); - MOCK_METHOD(quisp::modules::measurement_outcome, measure_density_independent, (), (override)); - MOCK_METHOD(void, setCompletelyMixedDensityMatrix, (), (override)); + MOCK_METHOD(quisp::types::MeasurementOutcome, measure_density_independent, (), (override)); MOCK_METHOD(void, setEntangledPartnerInfo, (IStationaryQubit *), (override)); - MOCK_METHOD(quisp::types::EigenvalueResult, measureX, (), (override)); - MOCK_METHOD(quisp::types::EigenvalueResult, measureY, (), (override)); - MOCK_METHOD(quisp::types::EigenvalueResult, measureZ, (), (override)); - MOCK_METHOD(void, cnotGate, (IStationaryQubit * control_qubit), (override)); MOCK_METHOD(void, hadamardGate, (), (override)); MOCK_METHOD(void, zGate, (), (override)); From 457aa1e6fb20f68df8d8b85b9656363fcddd9503 Mon Sep 17 00:00:00 2001 From: zigen Date: Mon, 4 Apr 2022 18:33:32 +0900 Subject: [PATCH 07/43] update BackendQubit def --- quisp/backends/ErrorTracking/Qubit.cc | 50 +++++++++++++++++++++++++-- quisp/backends/ErrorTracking/Qubit.h | 6 ++-- quisp/backends/interfaces/IQubit.h | 9 +++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index 81f149d19..903300fc5 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -247,6 +247,13 @@ void ErrorTrackingQubit::setFree() { has_relaxation_error = false; has_excitation_error = false; has_completely_mixed_error = false; + + density_matrix_collapsed << -111, -111, -111, -111; + no_density_matrix_nullptr_entangled_partner_ok = false; + if (entangled_partner != nullptr) { + // entangled_partner->entangled_partner = nullptr; + entangled_partner = nullptr; + } } void ErrorTrackingQubit::setRelaxedDensityMatrix() { density_matrix_collapsed << 0, 0, 0, 1; @@ -399,7 +406,15 @@ bool ErrorTrackingQubit::purifyX(IQubit* const control_qubit) { applyMemoryError(); et_control_qubit->applyMemoryError(); gateCNOT(control_qubit); - return correlationMeasureZ() == MeasureZResult::NO_X_ERROR; + auto result = correlationMeasureZ() == MeasureZResult::NO_X_ERROR; + + // Trash qubit has been measured. Now, break the entanglement info of the partner. + // There is no need to overwrite its density matrix since we are only tracking errors. + if (entangled_partner != nullptr) { + entangled_partner->no_density_matrix_nullptr_entangled_partner_ok = true; + entangled_partner->entangled_partner = nullptr; + } + return result; } bool ErrorTrackingQubit::purifyZ(IQubit* const target_qubit) { @@ -411,7 +426,16 @@ bool ErrorTrackingQubit::purifyZ(IQubit* const target_qubit) { et_target_qubit->applyMemoryError(); et_target_qubit->gateCNOT(this); gateH(); - return this->correlationMeasureZ() == MeasureZResult::NO_X_ERROR; + auto result = correlationMeasureZ() == MeasureZResult::NO_X_ERROR; + + // Trash qubit has been measured. Now, break the entanglement info of the partner. + // There is no need to overwrite its density matrix since we are only tracking errors. + if (entangled_partner != nullptr) { + entangled_partner->no_density_matrix_nullptr_entangled_partner_ok = true; + entangled_partner->entangled_partner = nullptr; + } + + return result; } Matrix2cd ErrorTrackingQubit::getErrorMatrix() { @@ -495,7 +519,7 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { } // if the partner qubit is measured, - if (this->partner_measured || has_completely_mixed_error || has_excitation_error || + if (this->partner_measured || has_completely_mixed_error || has_excitation_error || has_relaxation_error) { // The case when the density matrix is completely local to this qubit. if (density_matrix_collapsed(0, 0).real() == -111) { // We always need some kind of density matrix inside this if statement. @@ -624,6 +648,26 @@ MeasurementOperator ErrorTrackingQubit::randomMeasurementBasisSelection() { return this_measurement; } +void ErrorTrackingQubit::assertEntangledPartnerValid() { + if (entangled_partner == nullptr && density_matrix_collapsed(0, 0).real() == -111 && !no_density_matrix_nullptr_entangled_partner_ok) { + throw std::runtime_error("ErrorTrackingQubit::assertEntangledPartnerValid: something went wrong"); + } + if (entangled_partner != nullptr) { + if (entangled_partner->entangled_partner == nullptr) { + throw std::runtime_error("ErrorTrackingQubit::assertEntangledPartnerValid: 1. Entanglement tracking is not doing its job."); + } + if (entangled_partner->entangled_partner != this) { + throw std::runtime_error("ErrorTrackingQubit::assertEntangledPartnerValid: 2. Entanglement tracking is not doing its job."); + } + } +} + + void ErrorTrackingQubit::setEntangledPartner(IQubit * const partner){ + auto *et_partner_qubit = dynamic_cast(partner); + if (et_partner_qubit == nullptr) throw std::runtime_error("ErrorTrackingQubit::setEntangledPartner: invalid qubit type passed"); + entangled_partner = et_partner_qubit; + } + // Set error matrices. This is used in the process of simulating tomography. const SingleQubitErrorModel ErrorTrackingQubit::pauli = {.X = (Matrix2cd() << 0, 1, 1, 0).finished(), .Y = (Matrix2cd() << 0, Complex(0, -1), Complex(0, 1), 0).finished(), diff --git a/quisp/backends/ErrorTracking/Qubit.h b/quisp/backends/ErrorTracking/Qubit.h index 063ac85bd..c94097b02 100644 --- a/quisp/backends/ErrorTracking/Qubit.h +++ b/quisp/backends/ErrorTracking/Qubit.h @@ -51,13 +51,15 @@ class ErrorTrackingQubit : public IQubit { bool purifyX(IQubit* const control_qubit) override; bool purifyZ(IQubit* const target_qubit) override; MeasurementOutcome measureDensityIndependent() override; + void addErrorX() override; + void addErrorZ() override; + void assertEntangledPartnerValid() override; + void setEntangledPartner(IQubit * const partner) override; protected: void applySingleQubitGateError(SingleGateErrorModel const& err); void applyTwoQubitGateError(TwoQubitGateErrorModel const& err, ErrorTrackingQubit* another_qubit); void applyMemoryError(); - void addErrorX(); - void addErrorZ(); void setRelaxedDensityMatrix(); void setExcitedDensityMatrix(); void setCompletelyMixedDensityMatrix(); diff --git a/quisp/backends/interfaces/IQubit.h b/quisp/backends/interfaces/IQubit.h index 488d89c4d..f33176c7b 100644 --- a/quisp/backends/interfaces/IQubit.h +++ b/quisp/backends/interfaces/IQubit.h @@ -52,6 +52,15 @@ class IQubit { virtual EigenvalueResult localMeasureX() { throw std::runtime_error("localMeasureX not implemented"); } virtual EigenvalueResult localMeasureZ() { throw std::runtime_error("localMeasureZ not implemented"); } virtual MeasurementOutcome measureDensityIndependent() { throw std::runtime_error("measureDensityIndependent not implemented"); } + + // for debugging + virtual void assertEntangledPartnerValid() { throw std::runtime_error("assertEntangledPartnerValid not implemented"); }; + + // deprecated (ErrorTraciking Qubit specific) + virtual void addErrorX() { throw std::runtime_error("addErrorX is not implemented. will be revomed"); } + virtual void addErrorZ() { throw std::runtime_error("addErrorZ is not implemented. will be revomed"); } + virtual void setCompletelyMixedDensityMatrix() { throw std::runtime_error("setCompletelyMixedDensityMatrix is not implemented. will be revomed"); } + virtual void setEntangledPartner(IQubit * const partner) {throw std::runtime_error("setEntangledPartner is not implemented. will be revomed"); } }; } // namespace quisp::backends::abstract From dd365ee0461bbe7af313ee909119d761a0e339a4 Mon Sep 17 00:00:00 2001 From: zigen Date: Mon, 4 Apr 2022 18:36:36 +0900 Subject: [PATCH 08/43] move the qubit state assertion to backend --- .../QNIC/StationaryQubit/IStationaryQubit.h | 94 +-------------- .../QNIC/StationaryQubit/StationaryQubit.cc | 111 ++++++------------ .../QNIC/StationaryQubit/StationaryQubit.h | 22 ++-- .../StationaryQubit/StationaryQubit_test.cc | 2 - .../RealTimeController/RealTimeController.cc | 12 +- quisp/modules/QRSA/RuleEngine/RuleEngine.cc | 20 +--- 6 files changed, 47 insertions(+), 214 deletions(-) diff --git a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h index f7ac6ebe9..80a7cd601 100644 --- a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h @@ -58,52 +58,6 @@ struct emission_error_model { double Loss_error_ceil; }; -struct SingleGateErrorModel { - double pauli_error_rate; // Overall error rate - double Z_error_rate; - double X_error_rate; - double Y_error_rate; - - double No_error_ceil; - double Z_error_ceil; - double X_error_ceil; - double Y_error_ceil; -}; - -struct TwoQubitGateErrorModel { - double pauli_error_rate; // Overall error rate - double IZ_error_rate; - double ZI_error_rate; - double ZZ_error_rate; - double IY_error_rate; - double YI_error_rate; - double YY_error_rate; - double IX_error_rate; - double XI_error_rate; - double XX_error_rate; - - double No_error_ceil; - double IZ_error_ceil; - double ZI_error_ceil; - double ZZ_error_ceil; - double IY_error_ceil; - double YI_error_ceil; - double YY_error_ceil; - double IX_error_ceil; - double XI_error_ceil; - double XX_error_ceil; -}; - -struct memory_error_model { - double error_rate; // Overall error rate - double Z_error_rate; - double X_error_rate; - double Y_error_rate; - double excitation_error_rate; - double relaxation_error_rate; - double completely_mixed_rate; -}; - struct MeasurementErrorModel { double x_error_rate; double y_error_rate; @@ -126,41 +80,6 @@ struct single_qubit_error { Eigen::Matrix2cd I; }; -struct quantum_state { - Eigen::Matrix4cd state_in_density_matrix; - Eigen::Vector4cd state_in_ket; -}; - -struct measurement_output_probabilities { - double probability_plus_plus; // P(+,+) - double probability_minus_plus; // P(+,-) - double probability_plus_minus; // P(-,+) - double probability_minus_minus; // P(-,-) -}; - -struct measurement_operator { - Eigen::Matrix2cd plus; - Eigen::Matrix2cd minus; - Eigen::Vector2cd plus_ket; - Eigen::Vector2cd minus_ket; - char basis; -}; - -// Single qubit -struct measurement_operators { - measurement_operator X_basis; - measurement_operator Y_basis; - measurement_operator Z_basis; - Eigen::Matrix2cd identity; -}; - -struct measurement_outcome { - char basis; - bool outcome_is_plus; - char GOD_clean; - bool operator==(const measurement_outcome &outcome) const { return basis == outcome.basis && outcome_is_plus == outcome.outcome_is_plus && GOD_clean == outcome.GOD_clean; } -}; - class IStationaryQubit : public omnetpp::cSimpleModule { public: IStationaryQubit(){}; @@ -216,8 +135,8 @@ class IStationaryQubit : public omnetpp::cSimpleModule { /*GOD parameters*/ // SwappingAction virtual void setEntangledPartnerInfo(IStationaryQubit *partner) = 0; - - int stationary_qubit_address; + virtual backends::IQubit *getEntangledPartner() = 0; + int stationaryQubit_address; int node_address; int qnic_address; int qnic_type; @@ -230,8 +149,8 @@ class IStationaryQubit : public omnetpp::cSimpleModule { int action_index; bool no_density_matrix_nullptr_entangled_partner_ok; - /** Pointer to the entangled qubit*/ - IStationaryQubit *entangled_partner = nullptr; + virtual void assertEntangledPartnerValid() = 0; + /** Photon emitted at*/ omnetpp::simtime_t emitted_time = -1; // internal @@ -248,11 +167,6 @@ class IStationaryQubit : public omnetpp::cSimpleModule { MeasurementErrorModel Measurement_error; Eigen::Matrix2cd Density_Matrix_Collapsed; // Used when partner has been measured. - bool partner_measured; - bool completely_mixed; - bool excited_or_relaxed; - bool GOD_dm_Xerror; - bool GOD_dm_Zerror; }; } // namespace modules diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index dc2633bf4..5f6820b25 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -43,7 +43,6 @@ StationaryQubit::StationaryQubit() : provider(utils::ComponentProvider{this}) {} void StationaryQubit::initialize() { // read and set parameters emission_success_probability = par("emission_success_probability"); - Memory_Transition_matrix = MatrixXd::Zero(7, 7); // Get parameters from omnet stationary_qubit_address = par("stationary_qubit_address"); @@ -124,46 +123,45 @@ void StationaryQubit::setBusy() { // This is called at the beginning of the simulation (in initialization() above), and whenever it is reinitialized via the RealTimeController. void StationaryQubit::setFree(bool consumed) { qubit_ref->setFree(); - /********************************/ - num_purified = 0; + is_busy = false; locked = false; locked_ruleset_id = -1; locked_rule_id = -1; action_index = -1; - - is_busy = false; emitted_time = -1; updated_time = simTime(); - partner_measured = false; - completely_mixed = false; - excited_or_relaxed = false; - GOD_dm_Zerror = false; - GOD_dm_Xerror = false; - Density_Matrix_Collapsed << -111, -111, -111, -111; - no_density_matrix_nullptr_entangled_partner_ok = false; - god_entangled_stationary_qubit_address = -1; - god_entangled_node_address = -1; - god_entangled_qnic_address = -1; - god_entangled_qnic_type = -1; - god_err.has_x_error = false; - god_err.has_z_error = false; - god_err.has_excitation_error = false; - god_err.has_relaxation_error = false; - god_err.has_completely_mixed_error = false; - entangled_partner = nullptr; - EV_DEBUG << "Freeing this qubit!!!" << this << " at qnode: " << node_address << " qnic_type: " << qnic_type << " qnic_index: " << qnic_index << "\n"; - if (hasGUI()) { - if (consumed) { - bubble("Consumed!"); - getDisplayString().setTagArg("i", 1, "yellow"); - } else { - bubble("Failed to entangle!"); - getDisplayString().setTagArg("i", 1, "blue"); + /* + + + + + par("photon_emitted_at") = emitted_time.dbl(); + par("last_updated_at") = updated_time.dbl(); + par("GOD_Xerror") = false; + par("GOD_Zerror") = false; + par("GOD_CMerror") = false; + par("GOD_EXerror") = false; + par("GOD_REerror") = false; + par("GOD_CMerror") = false; + par("isBusy") = false; + EV_DEBUG << "Freeing this qubit!!!" << this << " at qnode: " << node_address << " qnic_type: " << qnic_type << " qnic_index: " << qnic_index << "\n"; + // GUI part + if (hasGUI()) { + if (consumed) { + bubble("Consumed!"); + getDisplayString().setTagArg("i", 1, "yellow"); + } else { + bubble("Failed to entangle!"); + getDisplayString().setTagArg("i", 1, "blue"); + } } - } + */ } +backends::IQubit StationaryQubit::*getEntangledPartner() { return qubit_ref->entangled_partner; } +void StationaryQubit::assertEntangledPartnerValid() { qubit_ref->assertEntangledPartnerValid(); } + /*To avoid disturbing this qubit.*/ void StationaryQubit::Lock(unsigned long rs_id, int rule_id, int action_id) { if (rs_id == -1 || rule_id == -1 || action_id == -1) { @@ -237,67 +235,26 @@ void StationaryQubit::emitPhoton(int pulse) { } // This gets direcltly invoked when darkcount happened in BellStateAnalyzer.cc. -void StationaryQubit::setCompletelyMixedDensityMatrix() { - this->Density_Matrix_Collapsed << (double)1 / (double)2, 0, 0, (double)1 / (double)2; - // std::cout<<"Dm completely mixed "<Density_Matrix_Collapsed<<"\n"; - this->completely_mixed = true; - this->excited_or_relaxed = false; - - if (this->entangled_partner != nullptr) { // Eliminate entangled information - this->entangled_partner->entangled_partner = nullptr; - this->entangled_partner = nullptr; - } - this->god_err.has_completely_mixed_error = true; - this->god_err.has_excitation_error = false; - this->god_err.has_relaxation_error = false; - this->god_err.has_x_error = false; - this->god_err.has_z_error = false; - this->GOD_dm_Xerror = false; - this->GOD_dm_Zerror = false; - if (hasGUI()) { - bubble("Completely mixed. darkcount"); - getDisplayString().setTagArg("i", 1, "black"); - } -} +[[deprecated]] void StationaryQubit::setCompletelyMixedDensityMatrix() { qubit_ref->setCompletelyMixedDensityMatrix(); } void StationaryQubit::setEntangledPartnerInfo(IStationaryQubit *partner) { // When BSA succeeds, this method gets invoked to store entangled partner information. // This will also be sent classically to the partner node afterwards. entangled_partner = partner; - god_entangled_stationary_qubit_address = partner->stationary_qubit_address; - god_entangled_node_address = partner->node_address; - god_entangled_qnic_address = partner->qnic_address; - god_entangled_qnic_type = partner->qnic_type; + qubit_ref->setEntangledPartner(partner->getQubitRef()); } /* Add another X error. If an X error already exists, then they cancel out */ -void StationaryQubit::addXerror() { this->god_err.has_x_error = !this->god_err.has_x_error; } +[[deprecated]] void StationaryQubit::addXerror() { qubit_ref->addErrorX(); } /* Add another Z error. If an Z error already exists, then they cancel out */ -void StationaryQubit::addZerror() { this->god_err.has_z_error = !this->god_err.has_z_error; } +[[deprecated]] void StationaryQubit::addZerror() { qubit_ref->addErrorZ(); } // Only tracks error propagation. If two booleans (Alice and Bob) agree (truetrue or falsefalse), keep the purified ebit. -bool StationaryQubit::Xpurify(IStationaryQubit *resource_qubit /*Controlled*/) { - if (qubit_ref == nullptr) throw std::runtime_error("qubit_ref nullptr error"); - - return qubit_ref->purifyX(check_and_cast(resource_qubit)->qubit_ref); } +bool StationaryQubit::Xpurify(IStationaryQubit *resource_qubit /*Controlled*/) { return qubit_ref->purifyX(check_and_cast(resource_qubit)->qubit_ref); } bool StationaryQubit::Zpurify(IStationaryQubit *resource_qubit /*Target*/) { return qubit_ref->purifyZ(check_and_cast(resource_qubit)->qubit_ref); } -Matrix2cd StationaryQubit::getErrorMatrix(StationaryQubit *qubit) { - if (qubit->god_err.has_completely_mixed_error || qubit->god_err.has_relaxation_error) { - error("CMerror in getErrorMatrix. Not supposed to happen."); - } - - auto has_z_err = qubit->god_err.has_z_error; - auto has_x_err = qubit->god_err.has_x_error; - - if (has_z_err && has_x_err) return Pauli.Y; - if (has_z_err) return Pauli.Z; - if (has_x_err) return Pauli.X; - return Pauli.I; -} - MeasurementOutcome StationaryQubit::measure_density_independent() { return qubit_ref->measureDensityIndependent(); } // protected internal graph backend functions diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index c9f222a76..1a9ed75ee 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -7,14 +7,14 @@ #pragma once #include +#include #include #include #include #include "IStationaryQubit.h" #include "QubitId.h" -namespace quisp { -namespace modules { +namespace quisp::modules { #define STATIONARYQUBIT_PULSE_BEGIN 0x01 #define STATIONARYQUBIT_PULSE_END 0x02 @@ -139,16 +139,12 @@ class StationaryQubit : public IStationaryQubit { void setExcitedDensityMatrix(); void addXerror(); void addZerror(); + backends::IQubit *getEntangledPartner() override; - double emission_success_probability; - - memory_error_model memory_err; + // for debugging + void assertEntangledPartnerValid() override; - single_qubit_error Pauli; - measurement_operators meas_op; - // https://arxiv.org/abs/1908.10758 Eq 5.2 - Eigen::MatrixXd Memory_Transition_matrix; /*I,X,Y,Z,Ex,Rl for single qubit. Unit in μs.*/ - int num_purified; + double emission_success_probability; bool locked; unsigned long locked_ruleset_id; @@ -160,11 +156,8 @@ class StationaryQubit : public IStationaryQubit { void handleMessage(omnetpp::cMessage *msg) override; messages::PhotonicQubit *generateEntangledPhoton(); void setBusy(); - // returns the matrix that represents the errors on the Bell pair. (e.g. XY, XZ and ZI...) Eigen::Matrix2cd getErrorMatrix(StationaryQubit *qubit); // returns the dm of the physical Bell pair. Used for tomography. - quantum_state getQuantumState(); - measurement_operator Random_Measurement_Basis_Selection(); void setMeasurementErrorModel(MeasurementErrorModel &model); // this is for debugging. class internal use only. @@ -173,5 +166,4 @@ class StationaryQubit : public IStationaryQubit { utils::ComponentProvider provider; }; -} // namespace modules -} // namespace quisp +} // namespace quisp::modules diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index ae70e7fc2..1c27aedd3 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -22,8 +22,6 @@ class Strategy : public TestComponentProviderStrategy { class StatQubitTarget : public StationaryQubit { public: - using StationaryQubit::getErrorMatrix; - using StationaryQubit::getQuantumState; using StationaryQubit::initialize; using StationaryQubit::par; StatQubitTarget() : StationaryQubit() { diff --git a/quisp/modules/QRSA/RealTimeController/RealTimeController.cc b/quisp/modules/QRSA/RealTimeController/RealTimeController.cc index 63b117105..cc53f9e8b 100644 --- a/quisp/modules/QRSA/RealTimeController/RealTimeController.cc +++ b/quisp/modules/QRSA/RealTimeController/RealTimeController.cc @@ -45,17 +45,7 @@ void RealTimeController::applyZGate(qrsa::IQubitRecord *const qubit_record) { } void RealTimeController::assertNoEntanglement(qrsa::IQubitRecord *const qubit_record) { auto *qubit = provider.getStationaryQubit(qubit_record); - if (qubit->entangled_partner == nullptr && qubit->Density_Matrix_Collapsed(0, 0).real() == -111 && !qubit->no_density_matrix_nullptr_entangled_partner_ok) { - error("something went wrong"); - } - if (qubit->entangled_partner != nullptr) { - if (qubit->entangled_partner->entangled_partner == nullptr) { - error("1. Entanglement tracking is not doing its job. in update resource E.S."); - } - if (qubit->entangled_partner->entangled_partner != qubit) { - error("2. Entanglement tracking is not doing its job. in update resource E.S."); - } - } + qubit->assertEntangledPartnerValid(); } } // namespace modules } // namespace quisp diff --git a/quisp/modules/QRSA/RuleEngine/RuleEngine.cc b/quisp/modules/QRSA/RuleEngine/RuleEngine.cc index 427f953b2..d98dd3135 100644 --- a/quisp/modules/QRSA/RuleEngine/RuleEngine.cc +++ b/quisp/modules/QRSA/RuleEngine/RuleEngine.cc @@ -500,25 +500,7 @@ void RuleEngine::freeFailedQubits_and_AddAsResource(int destAddr, int internal_q // Keep the entangled qubits auto *qubit_record = qnic_store->getQubitRecord(qnic_type, qnic_index, it->second.qubit_index); IStationaryQubit *qubit = provider.getStationaryQubit(qubit_record); - - // if the partner is null, not correct - if (qubit->entangled_partner != nullptr) { - if (qubit->entangled_partner->entangled_partner == nullptr) { - // my instance is null (no way) - error("1. Entanglement tracking is not doing its job."); - } - if (qubit->entangled_partner->entangled_partner != qubit) { - // partner's qubit doesn't point this qubit -> wrong - error("2. Entanglement tracking is not doing its job."); - } - } - - if (qubit->entangled_partner == nullptr && qubit->Density_Matrix_Collapsed(0, 0).real() == -111 && !qubit->no_density_matrix_nullptr_entangled_partner_ok) { - EV << "entangle partner null?" << qubit->entangled_partner << " == nullptr?\n"; - EV << "density matrix collapsed?" << qubit->Density_Matrix_Collapsed(0, 0).real() << "==-111?\n"; - EV << "here should be true" << qubit->no_density_matrix_nullptr_entangled_partner_ok << "\n"; - error("RuleEngine. Ebit succeed. but wrong"); - } + qubit->assertEntangledPartnerValid(); // Add qubit as available resource between NeighborQNodeAddress. bell_pair_store.insertEntangledQubit(neighborQNodeAddress, qubit_record); } From f70577ab946641671502bc9cac48cd75bbd7544f Mon Sep 17 00:00:00 2001 From: zigen Date: Wed, 6 Apr 2022 16:38:37 +0900 Subject: [PATCH 09/43] fix integration of backend to pass the unit tests --- quisp/backends/ErrorTracking/Qubit.cc | 18 +-- quisp/backends/ErrorTracking/Qubit.h | 7 +- .../ErrorTracking/Qubit_measurement_test.cc | 112 ++++++------------ quisp/backends/interfaces/IQubit.h | 7 +- .../BSA/BellStateAnalyzer.cc | 4 - .../QNIC/StationaryQubit/IStationaryQubit.h | 5 +- quisp/modules/QNIC/StationaryQubit/QubitId.h | 8 +- .../QNIC/StationaryQubit/StationaryQubit.cc | 15 ++- .../QNIC/StationaryQubit/StationaryQubit.h | 4 +- quisp/test_utils/TestUtils.h | 2 + .../mock_backends/MockBackendQubit.h | 15 +++ quisp/test_utils/mock_modules/MockQubit.h | 10 ++ 12 files changed, 109 insertions(+), 98 deletions(-) create mode 100644 quisp/test_utils/mock_backends/MockBackendQubit.h diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index 903300fc5..2ffe0ae8a 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -605,9 +605,9 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { // add measurement error auto rand_num = backend->dblrand(); - if (this_measurement.basis == measurement_op.x_basis.basis && rand_num < measurement_err.x_error_rate || - this_measurement.basis == measurement_op.y_basis.basis && rand_num < measurement_err.y_error_rate || - this_measurement.basis == measurement_op.z_basis.basis && rand_num < measurement_err.z_error_rate) { + if ((this_measurement.basis == measurement_op.x_basis.basis && rand_num < measurement_err.x_error_rate) || + (this_measurement.basis == measurement_op.y_basis.basis && rand_num < measurement_err.y_error_rate) || + (this_measurement.basis == measurement_op.z_basis.basis && rand_num < measurement_err.z_error_rate)) { Output_is_plus = !Output_is_plus; } @@ -662,11 +662,15 @@ void ErrorTrackingQubit::assertEntangledPartnerValid() { } } - void ErrorTrackingQubit::setEntangledPartner(IQubit * const partner){ - auto *et_partner_qubit = dynamic_cast(partner); +void ErrorTrackingQubit::setEntangledPartner(IQubit* const partner) { + auto* et_partner_qubit = dynamic_cast(partner); if (et_partner_qubit == nullptr) throw std::runtime_error("ErrorTrackingQubit::setEntangledPartner: invalid qubit type passed"); - entangled_partner = et_partner_qubit; - } + entangled_partner = et_partner_qubit; +} + +IQubit* const ErrorTrackingQubit::getEntangledPartner() const { return entangled_partner; } + +const IQubitId* const ErrorTrackingQubit::getId() const { return id; } // Set error matrices. This is used in the process of simulating tomography. const SingleQubitErrorModel ErrorTrackingQubit::pauli = {.X = (Matrix2cd() << 0, 1, 1, 0).finished(), diff --git a/quisp/backends/ErrorTracking/Qubit.h b/quisp/backends/ErrorTracking/Qubit.h index c94097b02..3be6f81d6 100644 --- a/quisp/backends/ErrorTracking/Qubit.h +++ b/quisp/backends/ErrorTracking/Qubit.h @@ -37,7 +37,7 @@ class ErrorTrackingQubit : public IQubit { ~ErrorTrackingQubit(); void setMemoryErrorRates(double x_error_rate, double y_error_rate, double z_error_rate, double excitation_rate, double relaxation_rate, double completely_mixed_rate); void reset(); - + const IQubitId* const getId() const override; void setFree() override; MeasureXResult correlationMeasureX() override; MeasureYResult correlationMeasureY() override; @@ -54,7 +54,8 @@ class ErrorTrackingQubit : public IQubit { void addErrorX() override; void addErrorZ() override; void assertEntangledPartnerValid() override; - void setEntangledPartner(IQubit * const partner) override; + void setEntangledPartner(IQubit* const partner) override; + IQubit* const getEntangledPartner() const override; protected: void applySingleQubitGateError(SingleGateErrorModel const& err); @@ -62,7 +63,7 @@ class ErrorTrackingQubit : public IQubit { void applyMemoryError(); void setRelaxedDensityMatrix(); void setExcitedDensityMatrix(); - void setCompletelyMixedDensityMatrix(); + void setCompletelyMixedDensityMatrix() override; Matrix2cd getErrorMatrix(); QuantumState getQuantumState(); MeasurementOperator randomMeasurementBasisSelection(); diff --git a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc index 98d23c73d..333302e8a 100644 --- a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc @@ -17,15 +17,18 @@ class EtQubitMeasurementTest : public ::testing::Test { backend = std::make_unique(std::unique_ptr(rng)); qubit = dynamic_cast(backend->getQubit(0)); - qubit2 = dynamic_cast(backend->getQubit(1)); another_qubit = dynamic_cast(backend->getQubit(2)); backend->setSimTime(SimTime(1, SIMTIME_US)); fillParams(qubit); - fillParams(qubit2); fillParams(another_qubit); } - + void reset() { + qubit->reset(); + another_qubit->reset(); + qubit->entangled_partner = another_qubit; + another_qubit->entangled_partner = qubit; + } void fillParams(Qubit* qubit) { // ceiled values should be: // No error= 0.1, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 @@ -81,7 +84,6 @@ class EtQubitMeasurementTest : public ::testing::Test { qubit->measurement_err.setParams(x_measurement_error_rate, y_measurement_error_rate, z_measurement_error_rate); } Qubit* qubit; - Qubit* qubit2; Qubit* another_qubit; std::unique_ptr backend; TestRNG* rng; @@ -197,8 +199,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { ASSERT_NE(qubit->entangled_partner, nullptr); ASSERT_NE(another_qubit->entangled_partner, nullptr); - qubit->reset(); - another_qubit->reset(); + reset(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -206,8 +207,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -215,8 +215,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -225,8 +224,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -235,8 +233,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -245,8 +242,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -255,8 +251,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -266,8 +261,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; @@ -280,9 +274,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { qubit->measurement_err.x_error_rate = 0.99; - qubit->entangled_partner = another_qubit; - another_qubit->entangled_partner = qubit; - + reset(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -290,8 +282,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -299,8 +290,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -309,8 +299,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -319,8 +308,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -329,8 +317,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -339,8 +326,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -350,8 +336,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; @@ -363,11 +348,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { } TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { - qubit->entangled_partner = another_qubit; - another_qubit->entangled_partner = qubit; - - qubit->reset(); - another_qubit->reset(); + reset(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -375,8 +356,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -384,8 +364,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -394,8 +373,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -404,8 +382,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -414,8 +391,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -424,8 +400,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -435,8 +410,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; @@ -449,11 +423,8 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { qubit->measurement_err.z_error_rate = 0.99; - qubit->entangled_partner = another_qubit; - another_qubit->entangled_partner = qubit; - qubit->reset(); - another_qubit->reset(); + reset(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -461,8 +432,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -470,8 +440,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -480,8 +449,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -490,8 +458,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -500,8 +467,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -510,8 +476,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -521,8 +486,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - qubit->reset(); - another_qubit->reset(); + reset(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; diff --git a/quisp/backends/interfaces/IQubit.h b/quisp/backends/interfaces/IQubit.h index f33176c7b..e4b111c2d 100644 --- a/quisp/backends/interfaces/IQubit.h +++ b/quisp/backends/interfaces/IQubit.h @@ -24,12 +24,16 @@ struct MeasurementOutcome { char GOD_clean; }; +class IQubitId; + class IQubit { public: IQubit(){}; virtual ~IQubit(){}; virtual void setFree() = 0; + virtual const IQubitId *const getId() const { throw std::runtime_error("getId is not implemented"); } + // // single qubit operations virtual void gateX() { throw std::runtime_error("gateX not implemented"); } virtual void gateY() { throw std::runtime_error("gateY not implemented"); } @@ -60,7 +64,8 @@ class IQubit { virtual void addErrorX() { throw std::runtime_error("addErrorX is not implemented. will be revomed"); } virtual void addErrorZ() { throw std::runtime_error("addErrorZ is not implemented. will be revomed"); } virtual void setCompletelyMixedDensityMatrix() { throw std::runtime_error("setCompletelyMixedDensityMatrix is not implemented. will be revomed"); } - virtual void setEntangledPartner(IQubit * const partner) {throw std::runtime_error("setEntangledPartner is not implemented. will be revomed"); } + virtual void setEntangledPartner(IQubit *const partner) { throw std::runtime_error("setEntangledPartner is not implemented. will be revomed"); } + virtual IQubit *const getEntangledPartner() const { throw std::runtime_error("getEntangledPartner is not implemented. will be revomed"); } }; } // namespace quisp::backends::abstract diff --git a/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc b/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc index ccfbf9a4c..97f47dfa1 100644 --- a/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc +++ b/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc @@ -292,10 +292,6 @@ void BellStateAnalyzer::GOD_updateEntangledInfoParameters_of_qubits() { right_statQubit_ptr->setEntangledPartnerInfo(left_statQubit_ptr); if (right_photon_Xerr) right_statQubit_ptr->addXerror(); if (right_photon_Zerr) right_statQubit_ptr->addZerror(); - if (right_statQubit_ptr->entangled_partner == nullptr || left_statQubit_ptr->entangled_partner == nullptr) { - std::cout << "Entangling failed\n"; - error("Entangling failed"); - } n_res++; emit(GOD_num_resSignal, n_res); } diff --git a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h index 80a7cd601..8e16aff43 100644 --- a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h @@ -135,7 +135,10 @@ class IStationaryQubit : public omnetpp::cSimpleModule { /*GOD parameters*/ // SwappingAction virtual void setEntangledPartnerInfo(IStationaryQubit *partner) = 0; - virtual backends::IQubit *getEntangledPartner() = 0; + virtual backends::IQubit *getEntangledPartner() const = 0; + virtual backends::IQubit *getBackendQubitRef() const = 0; + virtual int getPartnerStationaryQubitAddress() const = 0; + int stationaryQubit_address; int node_address; int qnic_address; diff --git a/quisp/modules/QNIC/StationaryQubit/QubitId.h b/quisp/modules/QNIC/StationaryQubit/QubitId.h index 9780231d0..f0e97bdbc 100644 --- a/quisp/modules/QNIC/StationaryQubit/QubitId.h +++ b/quisp/modules/QNIC/StationaryQubit/QubitId.h @@ -20,14 +20,14 @@ class QubitId : public quisp::backends::IQubitId { return node_addr == id.node_addr && qnic_index == id.qnic_index && qnic_type == id.qnic_type && qubit_addr == id.qubit_addr; } - protected: - // https://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine - void hashCombine(std::size_t& seed, int const& v) const { seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } - int node_addr; int qnic_index; int qnic_type; int qubit_addr; + + protected: + // https://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine + void hashCombine(std::size_t& seed, int const& v) const { seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } }; } // namespace quisp::modules::qubit_id diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index 5f6820b25..104480679 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -15,6 +15,8 @@ #include #include #include +#include "modules/QNIC/StationaryQubit/QubitId.h" +#include "omnetpp/cexception.h" using namespace Eigen; @@ -159,7 +161,7 @@ void StationaryQubit::setFree(bool consumed) { */ } -backends::IQubit StationaryQubit::*getEntangledPartner() { return qubit_ref->entangled_partner; } +backends::IQubit *StationaryQubit::getEntangledPartner() const { return qubit_ref->getEntangledPartner(); } void StationaryQubit::assertEntangledPartnerValid() { qubit_ref->assertEntangledPartnerValid(); } /*To avoid disturbing this qubit.*/ @@ -240,8 +242,15 @@ void StationaryQubit::emitPhoton(int pulse) { void StationaryQubit::setEntangledPartnerInfo(IStationaryQubit *partner) { // When BSA succeeds, this method gets invoked to store entangled partner information. // This will also be sent classically to the partner node afterwards. - entangled_partner = partner; - qubit_ref->setEntangledPartner(partner->getQubitRef()); + qubit_ref->setEntangledPartner(partner->getBackendQubitRef()); +} + +backends::IQubit *StationaryQubit::getBackendQubitRef() const { return qubit_ref; } +int StationaryQubit::getPartnerStationaryQubitAddress() const { + auto *partner_qubit_ref = qubit_ref->getEntangledPartner(); + auto *partner_id = dynamic_cast(partner_qubit_ref->getId()); + if (partner_id == nullptr) cRuntimeError("StationaryQubit::getPartnerStationaryQubitAddress: null partner backend qubit id cast"); + return partner_id->qubit_addr; } /* Add another X error. If an X error already exists, then they cancel out */ diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index 1a9ed75ee..bb63f469b 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -139,7 +139,9 @@ class StationaryQubit : public IStationaryQubit { void setExcitedDensityMatrix(); void addXerror(); void addZerror(); - backends::IQubit *getEntangledPartner() override; + backends::IQubit *getEntangledPartner() const override; + backends::IQubit *getBackendQubitRef() const override; + int getPartnerStationaryQubitAddress() const override; // for debugging void assertEntangledPartnerValid() override; diff --git a/quisp/test_utils/TestUtils.h b/quisp/test_utils/TestUtils.h index 8f6e1e543..96bf954f0 100644 --- a/quisp/test_utils/TestUtils.h +++ b/quisp/test_utils/TestUtils.h @@ -8,6 +8,7 @@ #include "StaticEnv.h" #include "TestComponentProviderStrategy.h" #include "UtilFunctions.h" +#include "mock_backends/MockBackendQubit.h" #include "mock_backends/MockQuantumBackend.h" #include "mock_modules/MockHardwareMonitor.h" #include "mock_modules/MockQubit.h" @@ -21,6 +22,7 @@ namespace quisp_test { // use these functions and classes in your unit test. using gate::TestGate; +using mock_backends::MockBackendQubit; using mock_backends::MockQuantumBackend; using mock_modules::hardware_monitor::MockHardwareMonitor; using mock_modules::qnic_store::MockQNicStore; diff --git a/quisp/test_utils/mock_backends/MockBackendQubit.h b/quisp/test_utils/mock_backends/MockBackendQubit.h new file mode 100644 index 000000000..f858cff1b --- /dev/null +++ b/quisp/test_utils/mock_backends/MockBackendQubit.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include +#include +#include +#include "backends/interfaces/IQubit.h" +#include "gmock/gmock-function-mocker.h" +namespace quisp_test::mock_backends { +class MockBackendQubit : public quisp::backends::abstract::IQubit { + public: + MOCK_METHOD(void, setFree, (), (override)); + MOCK_METHOD(void, setEntangledPartner, (IQubit * partner_qubit), (override)); +}; +} // namespace quisp_test::mock_backends diff --git a/quisp/test_utils/mock_modules/MockQubit.h b/quisp/test_utils/mock_modules/MockQubit.h index 5a83e5029..8ba9f4511 100644 --- a/quisp/test_utils/mock_modules/MockQubit.h +++ b/quisp/test_utils/mock_modules/MockQubit.h @@ -4,13 +4,17 @@ #include #include #include +#include "backends/Backends.h" #include "modules/QNIC.h" +#include "modules/QNIC/StationaryQubit/IStationaryQubit.h" #include "modules/QRSA/RuleEngine/BellPairStore/BellPairStore.h" namespace quisp_test { namespace mock_modules { namespace stationary_qubit { +using quisp::backends::IQubit; +using quisp::backends::IQubitId; using quisp::modules::IStationaryQubit; using quisp_test::utils::setParBool; using quisp_test::utils::setParDouble; @@ -20,6 +24,8 @@ class MockQubit : public IStationaryQubit { public: using IStationaryQubit::initialize; using IStationaryQubit::par; + IStationaryQubit *entangled_partner; + MOCK_METHOD(void, emitPhoton, (int pulse), (override)); MOCK_METHOD(void, setFree, (bool consumed), (override)); MOCK_METHOD(quisp::types::MeasureZResult, correlationMeasureZ, (), (override)); @@ -48,6 +54,10 @@ class MockQubit : public IStationaryQubit { MOCK_METHOD(void, sdgGate, (), (override)); MOCK_METHOD(void, excite, (), (override)); MOCK_METHOD(void, relax, (), (override)); + MOCK_METHOD(void, assertEntangledPartnerValid, (), (override)); + MOCK_METHOD(IQubit *const, getEntangledPartner, (), (const, override)); + MOCK_METHOD(IQubit *const, getBackendQubitRef, (), (const, override)); + MOCK_METHOD(int, getPartnerStationaryQubitAddress, (), (const, override)); MockQubit() : IStationaryQubit() { setComponentType(new module_type::TestModuleType("test qubit")); } MockQubit(quisp::modules::QNIC_type _type, quisp::modules::QNicIndex _qnic_index) : MockQubit() { From fc7d4692eae421ddd4751d2f414b35d794e334a4 Mon Sep 17 00:00:00 2001 From: zigen Date: Thu, 7 Apr 2022 00:46:18 +0900 Subject: [PATCH 10/43] fix typo --- quisp/backends/interfaces/IQubit.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/quisp/backends/interfaces/IQubit.h b/quisp/backends/interfaces/IQubit.h index e4b111c2d..0d877745a 100644 --- a/quisp/backends/interfaces/IQubit.h +++ b/quisp/backends/interfaces/IQubit.h @@ -61,11 +61,11 @@ class IQubit { virtual void assertEntangledPartnerValid() { throw std::runtime_error("assertEntangledPartnerValid not implemented"); }; // deprecated (ErrorTraciking Qubit specific) - virtual void addErrorX() { throw std::runtime_error("addErrorX is not implemented. will be revomed"); } - virtual void addErrorZ() { throw std::runtime_error("addErrorZ is not implemented. will be revomed"); } - virtual void setCompletelyMixedDensityMatrix() { throw std::runtime_error("setCompletelyMixedDensityMatrix is not implemented. will be revomed"); } - virtual void setEntangledPartner(IQubit *const partner) { throw std::runtime_error("setEntangledPartner is not implemented. will be revomed"); } - virtual IQubit *const getEntangledPartner() const { throw std::runtime_error("getEntangledPartner is not implemented. will be revomed"); } + virtual void addErrorX() { throw std::runtime_error("addErrorX is not implemented. will be removed"); } + virtual void addErrorZ() { throw std::runtime_error("addErrorZ is not implemented. will be removed"); } + virtual void setCompletelyMixedDensityMatrix() { throw std::runtime_error("setCompletelyMixedDensityMatrix is not implemented. will be removed"); } + virtual void setEntangledPartner(IQubit *const partner) { throw std::runtime_error("setEntangledPartner is not implemented. will be removed"); } + virtual IQubit *const getEntangledPartner() const { throw std::runtime_error("getEntangledPartner is not implemented. will be removed"); } }; } // namespace quisp::backends::abstract From d7132b9e93b65118e73c55328cbdaf41a6a0d5fd Mon Sep 17 00:00:00 2001 From: zigen Date: Tue, 12 Apr 2022 21:35:52 +0900 Subject: [PATCH 11/43] collect backend container's params --- quisp/backends/Backends.h | 6 +- quisp/backends/ErrorTracking/Backend.cc | 25 +++++ quisp/backends/ErrorTracking/Backend.h | 7 ++ quisp/backends/ErrorTracking/Configuration.h | 54 ++++++++++ quisp/backends/ErrorTracking/Qubit.cc | 9 ++ quisp/backends/ErrorTracking/Qubit.h | 2 + quisp/backends/interfaces/IConfiguration.h | 15 +++ quisp/backends/interfaces/IQuantumBackend.h | 3 + quisp/modules/Backend/Backend.cc | 47 +++++++- quisp/modules/Backend/Backend.h | 2 + quisp/modules/Backend/Backend_test.cc | 100 +++++++++++++++--- quisp/modules/common_types.h | 6 +- .../mock_backends/MockQuantumBackend.h | 2 + 13 files changed, 258 insertions(+), 20 deletions(-) create mode 100644 quisp/backends/ErrorTracking/Configuration.h create mode 100644 quisp/backends/interfaces/IConfiguration.h diff --git a/quisp/backends/Backends.h b/quisp/backends/Backends.h index f4f098a94..0dd30257b 100644 --- a/quisp/backends/Backends.h +++ b/quisp/backends/Backends.h @@ -1,13 +1,16 @@ #pragma once #include "ErrorTracking/Backend.h" -#include "backends/interfaces/IQubit.h" +#include "ErrorTracking/Configuration.h" +#include "interfaces/IConfiguration.h" #include "interfaces/IQuantumBackend.h" +#include "interfaces/IQubit.h" #include "interfaces/IQubitId.h" // the namespace for exposing the backend namespace quisp::backends { using abstract::EigenvalueResult; +using abstract::IConfiguration; using abstract::IQuantumBackend; using abstract::IQubit; using abstract::IQubitId; @@ -16,6 +19,7 @@ using abstract::MeasureXResult; using abstract::MeasureYResult; using abstract::MeasureZResult; using error_tracking::ErrorTrackingBackend; +using error_tracking::ErrorTrackingConfiguration; using error_tracking::ErrorTrackingQubit; } // namespace quisp::backends diff --git a/quisp/backends/ErrorTracking/Backend.cc b/quisp/backends/ErrorTracking/Backend.cc index d62320f10..0425ee6e7 100644 --- a/quisp/backends/ErrorTracking/Backend.cc +++ b/quisp/backends/ErrorTracking/Backend.cc @@ -1,15 +1,36 @@ #include "Backend.h" +#include +#include #include "Qubit.h" +#include "backends/ErrorTracking/Configuration.h" namespace quisp::backends::error_tracking { using error_tracking::ErrorTrackingQubit; +ErrorTrackingBackend::ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration) + : ErrorTrackingBackend(std::move(rng)) { + config = std::move(configuration); +} ErrorTrackingBackend::ErrorTrackingBackend(std::unique_ptr rng) : current_time(SimTime()), rng(std::move(rng)) {} + ErrorTrackingBackend::~ErrorTrackingBackend() { for (auto& pair : qubits) { delete pair.first; } } + +IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id, std::unique_ptr configuration) { + auto qubit = qubits.find(id); + + if (qubit != qubits.cend()) { + return qubit->second.get(); + } + auto original_qubit = std::make_unique(id, this); + auto* qubit_ptr = original_qubit.get(); + qubits.insert({id, std::move(original_qubit)}); + return qubit_ptr; +} + IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id) { auto qubit = qubits.find(id); @@ -21,6 +42,10 @@ IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id) { qubits.insert({id, std::move(original_qubit)}); return qubit_ptr; } +std::unique_ptr ErrorTrackingBackend::getDefaultConfiguration() const { + // copy the default backend configuration for each qubit + return std::make_unique(*config.get()); +} const SimTime& ErrorTrackingBackend::getSimTime() { return current_time; } void ErrorTrackingBackend::setSimTime(SimTime time) { current_time = time; } double ErrorTrackingBackend::dblrand() { return rng->doubleRandom(); } diff --git a/quisp/backends/ErrorTracking/Backend.h b/quisp/backends/ErrorTracking/Backend.h index ad38d944a..447b61476 100644 --- a/quisp/backends/ErrorTracking/Backend.h +++ b/quisp/backends/ErrorTracking/Backend.h @@ -3,12 +3,15 @@ #include #include +#include "../interfaces/IConfiguration.h" #include "../interfaces/IQuantumBackend.h" #include "../interfaces/IQubitId.h" #include "../interfaces/IRandomNumberGenerator.h" +#include "Configuration.h" #include "Qubit.h" namespace quisp::backends::error_tracking { +using abstract::IConfiguration; using abstract::IQuantumBackend; using abstract::IQubit; using abstract::IQubitId; @@ -19,8 +22,11 @@ using omnetpp::SimTime; class ErrorTrackingBackend : public IQuantumBackend { public: ErrorTrackingBackend(std::unique_ptr rng); + ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration); ~ErrorTrackingBackend(); IQubit* getQubit(const IQubitId* id) override; + IQubit* getQubit(const IQubitId* id, std::unique_ptr configuration) override; + std::unique_ptr getDefaultConfiguration() const; const SimTime& getSimTime() override; void setSimTime(SimTime time) override; double dblrand(); @@ -29,6 +35,7 @@ class ErrorTrackingBackend : public IQuantumBackend { std::unordered_map, IQubitId::Hash, IQubitId::Pred> qubits; SimTime current_time; const std::unique_ptr rng; + std::unique_ptr config; }; } // namespace quisp::backends::error_tracking diff --git a/quisp/backends/ErrorTracking/Configuration.h b/quisp/backends/ErrorTracking/Configuration.h new file mode 100644 index 000000000..72071e854 --- /dev/null +++ b/quisp/backends/ErrorTracking/Configuration.h @@ -0,0 +1,54 @@ +#pragma once + +#include "../interfaces/IConfiguration.h" +namespace quisp::backends::error_tracking { +/** +@brief Configuration class contains all parameters and provides the way to retrieve it +*/ +class ErrorTrackingConfiguration : public abstract::IConfiguration { + public: + ErrorTrackingConfiguration() {} + ~ErrorTrackingConfiguration() {} + // ErrorTrackingConfiguration(const ErrorTrackingConfiguration&c) = default; + + // list up all params + double memory_x_err_rate; + double memory_y_err_rate; + double memory_z_err_rate; + double memory_excitation_rate; + double memory_relaxation_rate; + double memory_completely_mixed_rate; + + double measurement_x_err_rate; + double measurement_y_err_rate; + double measurement_z_err_rate; + + double x_gate_x_err_ratio; + double x_gate_y_err_ratio; + double x_gate_z_err_ratio; + double x_gate_err_rate; + + double z_gate_x_err_ratio; + double z_gate_y_err_ratio; + double z_gate_z_err_ratio; + double z_gate_err_rate; + + double h_gate_x_err_ratio; + double h_gate_y_err_ratio; + double h_gate_z_err_ratio; + double h_gate_err_rate; + + double cnot_gate_iz_err_ratio; + double cnot_gate_zi_err_ratio; + double cnot_gate_zz_err_ratio; + double cnot_gate_ix_err_ratio; + double cnot_gate_xi_err_ratio; + double cnot_gate_xx_err_ratio; + double cnot_gate_iy_err_ratio; + double cnot_gate_yi_err_ratio; + double cnot_gate_yy_err_ratio; + double cnot_gate_err_rate; + + protected: +}; +} // namespace quisp::backends::error_tracking diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index 2ffe0ae8a..2f7ec4c12 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -7,6 +7,15 @@ ErrorTrackingQubit::ErrorTrackingQubit(const IQubitId* id, ErrorTrackingBackend* // emission_success_probability = par("emission_success_probability"); } ErrorTrackingQubit::~ErrorTrackingQubit() {} +void ErrorTrackingQubit::configure(std::unique_ptr c) { + setMemoryErrorRates(c->memory_x_err_rate, c->memory_y_err_rate, c->memory_z_err_rate, c->memory_excitation_rate, c->memory_relaxation_rate, c->memory_completely_mixed_rate); + measurement_err.setParams(c->measurement_x_err_rate, c->measurement_y_err_rate, c->measurement_z_err_rate); + gate_err_h.setParams(c->h_gate_x_err_ratio, c->h_gate_y_err_ratio, c->h_gate_z_err_ratio, c->h_gate_err_rate); + gate_err_x.setParams(c->x_gate_x_err_ratio, c->x_gate_y_err_ratio, c->x_gate_z_err_ratio, c->x_gate_err_rate); + gate_err_z.setParams(c->z_gate_x_err_ratio, c->z_gate_y_err_ratio, c->z_gate_z_err_ratio, c->z_gate_err_rate); + gate_err_cnot.setParams(c->cnot_gate_err_rate, c->cnot_gate_ix_err_ratio, c->cnot_gate_xi_err_ratio, c->cnot_gate_xx_err_ratio, c->cnot_gate_iz_err_ratio, + c->cnot_gate_zi_err_ratio, c->cnot_gate_zz_err_ratio, c->cnot_gate_iy_err_ratio, c->cnot_gate_yi_err_ratio, c->cnot_gate_yy_err_ratio); +} void ErrorTrackingQubit::setMemoryErrorRates(double x_error_rate, double y_error_rate, double z_error_rate, double excitation_rate, double relaxation_rate, double completely_mixed_rate) { memory_err.x_error_rate = x_error_rate; diff --git a/quisp/backends/ErrorTracking/Qubit.h b/quisp/backends/ErrorTracking/Qubit.h index 3be6f81d6..a557bb165 100644 --- a/quisp/backends/ErrorTracking/Qubit.h +++ b/quisp/backends/ErrorTracking/Qubit.h @@ -6,6 +6,7 @@ #include #include "../interfaces/IQuantumBackend.h" #include "../interfaces/IQubit.h" +#include "backends/ErrorTracking/Configuration.h" #include "omnetpp/simtime.h" #include "types.h" @@ -37,6 +38,7 @@ class ErrorTrackingQubit : public IQubit { ~ErrorTrackingQubit(); void setMemoryErrorRates(double x_error_rate, double y_error_rate, double z_error_rate, double excitation_rate, double relaxation_rate, double completely_mixed_rate); void reset(); + void configure(std::unique_ptr configuration); const IQubitId* const getId() const override; void setFree() override; MeasureXResult correlationMeasureX() override; diff --git a/quisp/backends/interfaces/IConfiguration.h b/quisp/backends/interfaces/IConfiguration.h new file mode 100644 index 000000000..755593ab8 --- /dev/null +++ b/quisp/backends/interfaces/IConfiguration.h @@ -0,0 +1,15 @@ +#pragma once +#include + +namespace quisp::backends::abstract { + +/** + * @brief just an interface for the configuration to the backend + */ +class IConfiguration { + public: + IConfiguration(){}; + virtual ~IConfiguration(){}; +}; + +} // namespace quisp::backends::abstract diff --git a/quisp/backends/interfaces/IQuantumBackend.h b/quisp/backends/interfaces/IQuantumBackend.h index 724864cad..1717ac294 100644 --- a/quisp/backends/interfaces/IQuantumBackend.h +++ b/quisp/backends/interfaces/IQuantumBackend.h @@ -1,5 +1,6 @@ #pragma once #include +#include "IConfiguration.h" #include "IQubitId.h" namespace quisp::backends::abstract { @@ -7,6 +8,7 @@ namespace quisp::backends::abstract { using omnetpp::SimTime; using omnetpp::SimTimeUnit; class IQubit; +class IConfigurationCollector; /** * @brief The abstract interface for a quantum backend. @@ -20,6 +22,7 @@ class IQuantumBackend { virtual ~IQuantumBackend(){}; virtual IQubit* getQubit(const IQubitId* id) = 0; + virtual IQubit* getQubit(const IQubitId* id, std::unique_ptr configuration) = 0; virtual const SimTime& getSimTime() = 0; virtual void setSimTime(SimTime time) = 0; diff --git a/quisp/modules/Backend/Backend.cc b/quisp/modules/Backend/Backend.cc index 7d0f7bf43..66e33e9c4 100644 --- a/quisp/modules/Backend/Backend.cc +++ b/quisp/modules/Backend/Backend.cc @@ -1,17 +1,62 @@ #include "Backend.h" namespace quisp::modules::backend { + BackendContainer::BackendContainer() {} + BackendContainer::~BackendContainer() {} + void BackendContainer::initialize() { auto backend_type = std::string(par("backendType").stringValue()); if (backend_type == "ErrorTrackingBackend") { - backend = std::make_unique(std::make_unique(this)); + configureErrorTrackingBackend(); } else { throw omnetpp::cRuntimeError("Unknown backend type: %s", backend_type.c_str()); } } +void BackendContainer::configureErrorTrackingBackend() { + auto conf = std::make_unique(); + conf->measurement_x_err_rate = par("Measurement_X_error_ratio").doubleValue(); + conf->measurement_y_err_rate = par("Measurement_Y_error_ratio").doubleValue(); + conf->measurement_z_err_rate = par("Measurement_Z_error_ratio").doubleValue(); + + conf->h_gate_err_rate = par("Hgate_error_rate").doubleValue(); + conf->h_gate_x_err_ratio = par("Hgate_X_error_ratio").doubleValue(); + conf->h_gate_y_err_ratio = par("Hgate_Y_error_ratio").doubleValue(); + conf->h_gate_z_err_ratio = par("Hgate_Z_error_ratio").doubleValue(); + + conf->x_gate_err_rate = par("Xgate_error_rate").doubleValue(); + conf->x_gate_x_err_ratio = par("Xgate_X_error_ratio").doubleValue(); + conf->x_gate_y_err_ratio = par("Xgate_Y_error_ratio").doubleValue(); + conf->x_gate_z_err_ratio = par("Xgate_Z_error_ratio").doubleValue(); + + conf->z_gate_err_rate = par("Zgate_error_rate").doubleValue(); + conf->z_gate_x_err_ratio = par("Zgate_X_error_ratio").doubleValue(); + conf->z_gate_y_err_ratio = par("Zgate_Y_error_ratio").doubleValue(); + conf->z_gate_z_err_ratio = par("Zgate_Z_error_ratio").doubleValue(); + + conf->cnot_gate_err_rate = par("CNOTgate_error_rate").doubleValue(); + conf->cnot_gate_iz_err_ratio = par("CNOTgate_IZ_error_ratio").doubleValue(); + conf->cnot_gate_zi_err_ratio = par("CNOTgate_ZI_error_ratio").doubleValue(); + conf->cnot_gate_zz_err_ratio = par("CNOTgate_ZZ_error_ratio").doubleValue(); + conf->cnot_gate_ix_err_ratio = par("CNOTgate_IX_error_ratio").doubleValue(); + conf->cnot_gate_xi_err_ratio = par("CNOTgate_XI_error_ratio").doubleValue(); + conf->cnot_gate_xx_err_ratio = par("CNOTgate_XX_error_ratio").doubleValue(); + conf->cnot_gate_iy_err_ratio = par("CNOTgate_IY_error_ratio").doubleValue(); + conf->cnot_gate_yi_err_ratio = par("CNOTgate_YI_error_ratio").doubleValue(); + conf->cnot_gate_yy_err_ratio = par("CNOTgate_YY_error_ratio").doubleValue(); + + conf->memory_x_err_rate = par("memory_X_error_rate").doubleValue(); + conf->memory_y_err_rate = par("memory_Y_error_rate").doubleValue(); + conf->memory_z_err_rate = par("memory_Z_error_rate").doubleValue(); + conf->memory_excitation_rate = par("memory_energy_excitation_rate").doubleValue(); + conf->memory_relaxation_rate = par("memory_energy_relaxation_rate").doubleValue(); + conf->memory_completely_mixed_rate = par("memory_completely_mixed_rate").doubleValue(); + + backend = std::make_unique(std::make_unique(this), std::move(conf)); +} + void BackendContainer::finish() {} IQuantumBackend* BackendContainer::getQuantumBackend() { diff --git a/quisp/modules/Backend/Backend.h b/quisp/modules/Backend/Backend.h index dfb39ffaa..ba66f9b0a 100644 --- a/quisp/modules/Backend/Backend.h +++ b/quisp/modules/Backend/Backend.h @@ -6,6 +6,7 @@ namespace quisp::modules::backend { using quisp::modules::common::ErrorTrackingBackend; +using quisp::modules::common::ErrorTrackingConfiguration; using quisp::modules::common::IQuantumBackend; using rng::RNG; @@ -20,6 +21,7 @@ class BackendContainer : public omnetpp::cSimpleModule { IQuantumBackend* getQuantumBackend(); protected: + void configureErrorTrackingBackend(); std::unique_ptr backend; }; diff --git a/quisp/modules/Backend/Backend_test.cc b/quisp/modules/Backend/Backend_test.cc index 12073ee5a..b5cc54286 100644 --- a/quisp/modules/Backend/Backend_test.cc +++ b/quisp/modules/Backend/Backend_test.cc @@ -7,6 +7,7 @@ namespace { using namespace quisp_test; using OriginalBackendContainer = quisp::modules::backend::BackendContainer; using quisp::modules::backend::ErrorTrackingBackend; +using quisp::modules::backend::ErrorTrackingConfiguration; class BackendContainer : public OriginalBackendContainer { public: @@ -16,32 +17,65 @@ class BackendContainer : public OriginalBackendContainer { ~BackendContainer() override {} }; -TEST(BackendContainer, constructor) { BackendContainer backend; } +class BackendContainerTest : public ::testing::Test { + protected: + virtual void SetUp() { + auto *sim = utils::prepareSimulation(); + backend = new BackendContainer(); + setParDouble(backend, "Measurement_error_rate", .01); + setParDouble(backend, "Measurement_X_error_ratio", .02); + setParDouble(backend, "Measurement_Y_error_ratio", .03); + setParDouble(backend, "Measurement_Z_error_ratio", .04); + setParDouble(backend, "Hgate_error_rate", .05); + setParDouble(backend, "Hgate_X_error_ratio", .06); + setParDouble(backend, "Hgate_Y_error_ratio", .07); + setParDouble(backend, "Hgate_Z_error_ratio", .08); + setParDouble(backend, "Xgate_error_rate", .06); + setParDouble(backend, "Xgate_X_error_ratio", .07); + setParDouble(backend, "Xgate_Y_error_ratio", .08); + setParDouble(backend, "Xgate_Z_error_ratio", .09); + setParDouble(backend, "Zgate_error_rate", .10); + setParDouble(backend, "Zgate_X_error_ratio", .11); + setParDouble(backend, "Zgate_Y_error_ratio", .12); + setParDouble(backend, "Zgate_Z_error_ratio", .13); + setParDouble(backend, "CNOTgate_error_rate", .14); + setParDouble(backend, "CNOTgate_IX_error_ratio", .15); + setParDouble(backend, "CNOTgate_XI_error_ratio", .16); + setParDouble(backend, "CNOTgate_XX_error_ratio", .17); + setParDouble(backend, "CNOTgate_IY_error_ratio", .18); + setParDouble(backend, "CNOTgate_YI_error_ratio", .19); + setParDouble(backend, "CNOTgate_YY_error_ratio", .20); + setParDouble(backend, "CNOTgate_IZ_error_ratio", .21); + setParDouble(backend, "CNOTgate_ZI_error_ratio", .22); + setParDouble(backend, "CNOTgate_ZZ_error_ratio", .23); + setParDouble(backend, "memory_X_error_rate", .24); + setParDouble(backend, "memory_Y_error_rate", .25); + setParDouble(backend, "memory_Z_error_rate", .26); + setParDouble(backend, "memory_energy_excitation_rate", .27); + setParDouble(backend, "memory_energy_relaxation_rate", .28); + setParDouble(backend, "memory_completely_mixed_rate", .29); + sim->registerComponent(backend); + } + BackendContainer *backend; +}; + +TEST_F(BackendContainerTest, constructor) { BackendContainer backend; } -TEST(BackendContainer, callInitialize) { - auto *sim = utils::prepareSimulation(); - BackendContainer *backend = new BackendContainer(); - sim->registerComponent(backend); - setParStr(backend, "backend_type", "ErrorTrackingBackend"); +TEST_F(BackendContainerTest, callInitialize) { + setParStr(backend, "backendType", "ErrorTrackingBackend"); EXPECT_EQ(backend->backend, nullptr); backend->callInitialize(); EXPECT_NE(backend->backend, nullptr); } -TEST(BackendContainer, callInitializeWithInvalidBackend) { - auto *sim = utils::prepareSimulation(); - BackendContainer *backend = new BackendContainer(); - sim->registerComponent(backend); - setParStr(backend, "backend_type", "SomeInvalidBackend"); +TEST_F(BackendContainerTest, callInitializeWithInvalidBackend) { + setParStr(backend, "backendType", "SomeInvalidBackend"); EXPECT_EQ(backend->backend, nullptr); EXPECT_THROW(backend->callInitialize(), omnetpp::cRuntimeError); } -TEST(BackendContainer, getQuantumBackend) { - auto *sim = utils::prepareSimulation(); - BackendContainer *backend = new BackendContainer(); - sim->registerComponent(backend); - setParStr(backend, "backend_type", "ErrorTrackingBackend"); +TEST_F(BackendContainerTest, getQuantumBackend) { + setParStr(backend, "backendType", "ErrorTrackingBackend"); backend->callInitialize(); ASSERT_NE(backend->backend, nullptr); auto *b = backend->getQuantumBackend(); @@ -49,4 +83,38 @@ TEST(BackendContainer, getQuantumBackend) { auto *et_backend = dynamic_cast(b); EXPECT_NE(et_backend, nullptr); } + +TEST_F(BackendContainerTest, getBackendConfiguration) { + setParStr(backend, "backendType", "ErrorTrackingBackend"); + backend->callInitialize(); + ASSERT_NE(backend->backend, nullptr); + auto *b = backend->getQuantumBackend(); + ASSERT_NE(b, nullptr); + auto *et_backend = dynamic_cast(b); + + auto conf = et_backend->getDefaultConfiguration(); + ASSERT_NE(conf, nullptr); + auto et_conf = dynamic_cast(conf.get()); + ASSERT_NE(et_conf, nullptr); +} + +TEST_F(BackendContainerTest, getCopyOfBackendConfiguration) { + setParStr(backend, "backendType", "ErrorTrackingBackend"); + backend->callInitialize(); + ASSERT_NE(backend->backend, nullptr); + auto *b = backend->getQuantumBackend(); + ASSERT_NE(b, nullptr); + auto *et_backend = dynamic_cast(b); + + auto conf = et_backend->getDefaultConfiguration(); + auto et_conf = dynamic_cast(conf.get()); + + auto conf2 = et_backend->getDefaultConfiguration(); + auto et_conf2 = dynamic_cast(conf2.get()); + + // confirm et_conf and et_conf2 are different intstances + et_conf->cnot_gate_err_rate = 10; + EXPECT_NE(et_conf->cnot_gate_err_rate, et_conf2->cnot_gate_err_rate); + EXPECT_NE(et_conf, et_conf2); +} } // namespace diff --git a/quisp/modules/common_types.h b/quisp/modules/common_types.h index 086134816..649e8ccac 100644 --- a/quisp/modules/common_types.h +++ b/quisp/modules/common_types.h @@ -10,7 +10,9 @@ using QNicType = int; using QubitIndex = int; using QubitId = std::tuple; using IBackendQubit = quisp::backends::IQubit; +using quisp::backends::ErrorTrackingBackend; +using quisp::backends::ErrorTrackingConfiguration; +using quisp::backends::IConfiguration; +using quisp::backends::IQuantumBackend; using quisp::backends::IQubitId; -using IQuantumBackend = quisp::backends::IQuantumBackend; -using ErrorTrackingBackend = quisp::backends::ErrorTrackingBackend; } // namespace quisp::modules::common diff --git a/quisp/test_utils/mock_backends/MockQuantumBackend.h b/quisp/test_utils/mock_backends/MockQuantumBackend.h index 2a9a7b1a3..43b1f21bd 100644 --- a/quisp/test_utils/mock_backends/MockQuantumBackend.h +++ b/quisp/test_utils/mock_backends/MockQuantumBackend.h @@ -7,11 +7,13 @@ namespace quisp_test::mock_backends { using quisp::modules::common::IBackendQubit; +using quisp::modules::common::IConfiguration; using quisp::modules::common::IQuantumBackend; using quisp::modules::common::IQubitId; class MockQuantumBackend : public IQuantumBackend { public: MOCK_METHOD(IBackendQubit *, getQubit, (const IQubitId *), (override)); + MOCK_METHOD(IBackendQubit *, getQubit, (const IQubitId *, std::unique_ptr configuration), (override)); MOCK_METHOD(const SimTime &, getSimTime, (), (override)); MOCK_METHOD(void, setSimTime, (SimTime time), (override)); }; From 3983534f7a4028af611907a30811878cd1c4b317 Mon Sep 17 00:00:00 2001 From: zigen Date: Wed, 13 Apr 2022 00:48:54 +0900 Subject: [PATCH 12/43] temp: overwrite backend qubit config with StationaryQubit params --- quisp/backends/ErrorTracking/Backend.cc | 5 +- quisp/backends/ErrorTracking/Backend.h | 3 +- quisp/backends/ErrorTracking/Backend_test.cc | 3 +- quisp/backends/ErrorTracking/Qubit.cc | 7 ++- quisp/backends/ErrorTracking/Qubit.h | 1 + .../ErrorTracking/Qubit_gate_error_test.cc | 2 +- .../ErrorTracking/Qubit_measurement_test.cc | 2 +- .../ErrorTracking/Qubit_memory_error_test.cc | 2 +- quisp/backends/ErrorTracking/test.h | 4 +- quisp/backends/interfaces/IQuantumBackend.h | 2 + .../QNIC/StationaryQubit/StationaryQubit.cc | 55 ++++++++++++++++++- .../QNIC/StationaryQubit/StationaryQubit.h | 7 ++- .../StationaryQubit_measurement_test.cc | 1 - .../StationaryQubit/StationaryQubit_test.cc | 48 +++++++++++----- .../mock_backends/MockQuantumBackend.h | 1 + 15 files changed, 110 insertions(+), 33 deletions(-) diff --git a/quisp/backends/ErrorTracking/Backend.cc b/quisp/backends/ErrorTracking/Backend.cc index 0425ee6e7..6771a348f 100644 --- a/quisp/backends/ErrorTracking/Backend.cc +++ b/quisp/backends/ErrorTracking/Backend.cc @@ -8,10 +8,9 @@ namespace quisp::backends::error_tracking { using error_tracking::ErrorTrackingQubit; ErrorTrackingBackend::ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration) - : ErrorTrackingBackend(std::move(rng)) { + : current_time(SimTime()), rng(std::move(rng)) { config = std::move(configuration); } -ErrorTrackingBackend::ErrorTrackingBackend(std::unique_ptr rng) : current_time(SimTime()), rng(std::move(rng)) {} ErrorTrackingBackend::~ErrorTrackingBackend() { for (auto& pair : qubits) { @@ -42,7 +41,7 @@ IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id) { qubits.insert({id, std::move(original_qubit)}); return qubit_ptr; } -std::unique_ptr ErrorTrackingBackend::getDefaultConfiguration() const { +std::unique_ptr ErrorTrackingBackend::getDefaultConfiguration() const { // copy the default backend configuration for each qubit return std::make_unique(*config.get()); } diff --git a/quisp/backends/ErrorTracking/Backend.h b/quisp/backends/ErrorTracking/Backend.h index 447b61476..3680f3cb5 100644 --- a/quisp/backends/ErrorTracking/Backend.h +++ b/quisp/backends/ErrorTracking/Backend.h @@ -21,12 +21,11 @@ using omnetpp::SimTime; class ErrorTrackingBackend : public IQuantumBackend { public: - ErrorTrackingBackend(std::unique_ptr rng); ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration); ~ErrorTrackingBackend(); IQubit* getQubit(const IQubitId* id) override; IQubit* getQubit(const IQubitId* id, std::unique_ptr configuration) override; - std::unique_ptr getDefaultConfiguration() const; + std::unique_ptr getDefaultConfiguration() const override; const SimTime& getSimTime() override; void setSimTime(SimTime time) override; double dblrand(); diff --git a/quisp/backends/ErrorTracking/Backend_test.cc b/quisp/backends/ErrorTracking/Backend_test.cc index ccc0ba456..39de2a92f 100644 --- a/quisp/backends/ErrorTracking/Backend_test.cc +++ b/quisp/backends/ErrorTracking/Backend_test.cc @@ -3,6 +3,7 @@ #include #include #include "../interfaces/IRandomNumberGenerator.h" +#include "Configuration.h" #include "test.h" namespace { @@ -15,7 +16,7 @@ class EtBackendTest : public ::testing::Test { virtual void SetUp() { SimTime::setScaleExp(-9); rng = new TestRNG(); - backend = std::make_unique(std::unique_ptr(rng)); + backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); } TestRNG* rng; std::unique_ptr backend; diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index 2f7ec4c12..9bf0ca4e6 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -3,10 +3,10 @@ #include "Backend.h" namespace quisp::backends::error_tracking { -ErrorTrackingQubit::ErrorTrackingQubit(const IQubitId* id, ErrorTrackingBackend* const backend) : id(id), memory_transition_matrix(MatrixXd::Zero(7, 7)), backend(backend) { - // emission_success_probability = par("emission_success_probability"); -} +ErrorTrackingQubit::ErrorTrackingQubit(const IQubitId* id, ErrorTrackingBackend* const backend) : id(id), memory_transition_matrix(MatrixXd::Zero(7, 7)), backend(backend) {} + ErrorTrackingQubit::~ErrorTrackingQubit() {} + void ErrorTrackingQubit::configure(std::unique_ptr c) { setMemoryErrorRates(c->memory_x_err_rate, c->memory_y_err_rate, c->memory_z_err_rate, c->memory_excitation_rate, c->memory_relaxation_rate, c->memory_completely_mixed_rate); measurement_err.setParams(c->measurement_x_err_rate, c->measurement_y_err_rate, c->measurement_z_err_rate); @@ -16,6 +16,7 @@ void ErrorTrackingQubit::configure(std::unique_ptr c gate_err_cnot.setParams(c->cnot_gate_err_rate, c->cnot_gate_ix_err_ratio, c->cnot_gate_xi_err_ratio, c->cnot_gate_xx_err_ratio, c->cnot_gate_iz_err_ratio, c->cnot_gate_zi_err_ratio, c->cnot_gate_zz_err_ratio, c->cnot_gate_iy_err_ratio, c->cnot_gate_yi_err_ratio, c->cnot_gate_yy_err_ratio); } + void ErrorTrackingQubit::setMemoryErrorRates(double x_error_rate, double y_error_rate, double z_error_rate, double excitation_rate, double relaxation_rate, double completely_mixed_rate) { memory_err.x_error_rate = x_error_rate; diff --git a/quisp/backends/ErrorTracking/Qubit.h b/quisp/backends/ErrorTracking/Qubit.h index a557bb165..c60afdad1 100644 --- a/quisp/backends/ErrorTracking/Qubit.h +++ b/quisp/backends/ErrorTracking/Qubit.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include #include diff --git a/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc b/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc index ee9c7971e..fcc104607 100644 --- a/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc @@ -15,7 +15,7 @@ class EtQubitGateErrorTest : public ::testing::Test { SimTime::setScaleExp(-9); rng = new TestRNG(); rng->double_value = .0; - backend = std::make_unique(std::unique_ptr(rng)); + backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); qubit = dynamic_cast(backend->getQubit(new QubitId(0))); if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); qubit2 = dynamic_cast(backend->getQubit(new QubitId(1))); diff --git a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc index 333302e8a..fd2e78200 100644 --- a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc @@ -15,7 +15,7 @@ class EtQubitMeasurementTest : public ::testing::Test { rng = new TestRNG(); rng->double_value = .0; - backend = std::make_unique(std::unique_ptr(rng)); + backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); qubit = dynamic_cast(backend->getQubit(0)); another_qubit = dynamic_cast(backend->getQubit(2)); diff --git a/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc b/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc index 7ec971692..18de1629a 100644 --- a/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc @@ -20,7 +20,7 @@ class ETQubitMemoryErrorTest : public ::testing::Test { SimTime::setScaleExp(-9); rng = new TestRNG(); rng->double_value = .0; - backend = std::make_unique(std::unique_ptr(rng)); + backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); qubit = dynamic_cast(backend->getQubit(0)); partner_qubit = dynamic_cast(backend->getQubit(1)); if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index 7b6e9f796..2ac430dbd 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -6,6 +6,7 @@ #include "../interfaces/IQubitId.h" #include "../interfaces/IRandomNumberGenerator.h" #include "Backend.h" +#include "Configuration.h" #include "Qubit.h" namespace quisp_test::backends { @@ -13,6 +14,7 @@ using omnetpp::SimTime; using ::quisp::backends::abstract::IQubit; using ::quisp::backends::abstract::IQubitId; using ::quisp::backends::error_tracking::ErrorTrackingBackend; +using ::quisp::backends::error_tracking::ErrorTrackingConfiguration; using ::quisp::backends::error_tracking::ErrorTrackingQubit; using namespace ::quisp::backends; using namespace ::quisp::backends::abstract; @@ -76,7 +78,7 @@ class Qubit : public ErrorTrackingQubit { class Backend : public ErrorTrackingBackend { public: using ErrorTrackingBackend::qubits; - Backend(std::unique_ptr rng) : ErrorTrackingBackend(std::move(rng)) {} + Backend(std::unique_ptr rng, std::unique_ptr config) : ErrorTrackingBackend(std::move(rng), std::move(config)) {} IQubit* getQubit(int id) { return getQubit(new QubitId(id)); } IQubit* getQubit(const IQubitId* id) override { auto qubit = qubits.find(id); diff --git a/quisp/backends/interfaces/IQuantumBackend.h b/quisp/backends/interfaces/IQuantumBackend.h index 1717ac294..07a443c92 100644 --- a/quisp/backends/interfaces/IQuantumBackend.h +++ b/quisp/backends/interfaces/IQuantumBackend.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "IConfiguration.h" #include "IQubitId.h" @@ -23,6 +24,7 @@ class IQuantumBackend { virtual IQubit* getQubit(const IQubitId* id) = 0; virtual IQubit* getQubit(const IQubitId* id, std::unique_ptr configuration) = 0; + virtual std::unique_ptr getDefaultConfiguration() const = 0; virtual const SimTime& getSimTime() = 0; virtual void setSimTime(SimTime time) = 0; diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index 104480679..aa20b3d94 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -60,8 +60,9 @@ void StationaryQubit::initialize() { // initialize variables for graph state representation tracking vertex_operator = CliffordOperator::H; - auto *backend = provider.getQuantumBackend(); - qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationary_qubit_address)); + backend = provider.getQuantumBackend(); + auto config = prepareBackendQubitConfiguration(); + qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationaryQubit_address), std::move(config)); if (qubit_ref == nullptr) throw std::runtime_error("qubit_ref nullptr error"); setFree(false); @@ -71,6 +72,56 @@ void StationaryQubit::initialize() { WATCH(is_busy); } +void StationaryQubit::tryToAssignParDouble(double &field, const char *par_name) { + int par_index = findPar(par_name); + if (par_index == -1) return; + field = par(par_index).doubleValue(); +} + +std::unique_ptr StationaryQubit::prepareBackendQubitConfiguration() { + auto conf = backend->getDefaultConfiguration(); + if (auto et_conf = dynamic_cast(conf.get())) { + tryToAssignParDouble(et_conf->measurement_x_err_rate, "Measurement_X_error_ratio"); + et_conf->measurement_x_err_rate = par("Measurement_X_error_ratio").doubleValue(); + et_conf->measurement_y_err_rate = par("Measurement_Y_error_ratio").doubleValue(); + et_conf->measurement_z_err_rate = par("Measurement_Z_error_ratio").doubleValue(); + + et_conf->h_gate_err_rate = par("Hgate_error_rate").doubleValue(); + et_conf->h_gate_x_err_ratio = par("Hgate_X_error_ratio").doubleValue(); + et_conf->h_gate_y_err_ratio = par("Hgate_Y_error_ratio").doubleValue(); + et_conf->h_gate_z_err_ratio = par("Hgate_Z_error_ratio").doubleValue(); + + et_conf->x_gate_err_rate = par("Xgate_error_rate").doubleValue(); + et_conf->x_gate_x_err_ratio = par("Xgate_X_error_ratio").doubleValue(); + et_conf->x_gate_y_err_ratio = par("Xgate_Y_error_ratio").doubleValue(); + et_conf->x_gate_z_err_ratio = par("Xgate_Z_error_ratio").doubleValue(); + + et_conf->z_gate_err_rate = par("Zgate_error_rate").doubleValue(); + et_conf->z_gate_x_err_ratio = par("Zgate_X_error_ratio").doubleValue(); + et_conf->z_gate_y_err_ratio = par("Zgate_Y_error_ratio").doubleValue(); + et_conf->z_gate_z_err_ratio = par("Zgate_Z_error_ratio").doubleValue(); + + et_conf->cnot_gate_err_rate = par("CNOTgate_error_rate").doubleValue(); + et_conf->cnot_gate_iz_err_ratio = par("CNOTgate_IZ_error_ratio").doubleValue(); + et_conf->cnot_gate_zi_err_ratio = par("CNOTgate_ZI_error_ratio").doubleValue(); + et_conf->cnot_gate_zz_err_ratio = par("CNOTgate_ZZ_error_ratio").doubleValue(); + et_conf->cnot_gate_ix_err_ratio = par("CNOTgate_IX_error_ratio").doubleValue(); + et_conf->cnot_gate_xi_err_ratio = par("CNOTgate_XI_error_ratio").doubleValue(); + et_conf->cnot_gate_xx_err_ratio = par("CNOTgate_XX_error_ratio").doubleValue(); + et_conf->cnot_gate_iy_err_ratio = par("CNOTgate_IY_error_ratio").doubleValue(); + et_conf->cnot_gate_yi_err_ratio = par("CNOTgate_YI_error_ratio").doubleValue(); + et_conf->cnot_gate_yy_err_ratio = par("CNOTgate_YY_error_ratio").doubleValue(); + + et_conf->memory_x_err_rate = par("memory_X_error_rate").doubleValue(); + et_conf->memory_y_err_rate = par("memory_Y_error_rate").doubleValue(); + et_conf->memory_z_err_rate = par("memory_Z_error_rate").doubleValue(); + et_conf->memory_excitation_rate = par("memory_energy_excitation_rate").doubleValue(); + et_conf->memory_relaxation_rate = par("memory_energy_relaxation_rate").doubleValue(); + et_conf->memory_completely_mixed_rate = par("memory_completely_mixed_rate").doubleValue(); + } + return conf; +} + void StationaryQubit::finish() {} /** diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index bb63f469b..bb0b1debc 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -13,6 +13,7 @@ #include #include "IStationaryQubit.h" #include "QubitId.h" +#include "backends/interfaces/IQuantumBackend.h" namespace quisp::modules { @@ -28,6 +29,7 @@ namespace quisp::modules { typedef std::complex Complex; using quisp::modules::common::IBackendQubit; +using quisp::modules::common::IConfiguration; using quisp::modules::common::IQuantumBackend; class StationaryQubit : public IStationaryQubit { @@ -159,13 +161,14 @@ class StationaryQubit : public IStationaryQubit { messages::PhotonicQubit *generateEntangledPhoton(); void setBusy(); Eigen::Matrix2cd getErrorMatrix(StationaryQubit *qubit); - // returns the dm of the physical Bell pair. Used for tomography. - void setMeasurementErrorModel(MeasurementErrorModel &model); + std::unique_ptr prepareBackendQubitConfiguration(); + void tryToAssignParDouble(double &field, const char *par_name); // this is for debugging. class internal use only. // and it's different from QubitRecord's one. bool is_busy; utils::ComponentProvider provider; + IQuantumBackend *backend; }; } // namespace quisp::modules diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc index fd29b49cb..220554942 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc @@ -31,7 +31,6 @@ class StatQubitTarget : public StationaryQubit { using StationaryQubit::localMeasureY; using StationaryQubit::localMeasureZ; using StationaryQubit::par; - using StationaryQubit::setMeasurementErrorModel; StatQubitTarget() : StationaryQubit() { setComponentType(new TestModuleType("test qubit")); provider.setStrategy(std::make_unique()); diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 1c27aedd3..8a37127f5 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -1,10 +1,15 @@ #include "StationaryQubit.h" +#include #include #include #include #include #include +#include "backends/interfaces/IConfiguration.h" +#include "backends/interfaces/IQuantumBackend.h" +#include "test_utils/mock_backends/MockQuantumBackend.h" +using namespace testing; using namespace quisp::modules; using namespace quisp::modules::common; using namespace quisp_test; @@ -14,19 +19,19 @@ namespace { class Strategy : public TestComponentProviderStrategy { public: - Strategy() : backend(new MockQuantumBackend()) {} + Strategy(IQuantumBackend *backend) : backend(backend) {} ~Strategy() {} IQuantumBackend *getQuantumBackend() override { return backend; } - MockQuantumBackend *backend; + IQuantumBackend *backend; }; class StatQubitTarget : public StationaryQubit { public: using StationaryQubit::initialize; using StationaryQubit::par; - StatQubitTarget() : StationaryQubit() { + StatQubitTarget(IQuantumBackend *backend) : StationaryQubit() { setComponentType(new TestModuleType("test qubit")); - provider.setStrategy(std::make_unique()); + provider.setStrategy(std::make_unique(backend)); } void reset() { setFree(true); @@ -82,6 +87,20 @@ class StatQubitTarget : public StationaryQubit { } }; +class StatQubitTest : public ::testing::Test { + protected: + void SetUp() { + prepareSimulation(); + backend = new MockQuantumBackend(); + qubit = new StatQubitTarget(backend); + qubit->fillParams(); + } + void TearDown() { delete backend; } + + StatQubitTarget *qubit; + MockQuantumBackend *backend; +}; + // TEST(StatQubitTest, initialize_memory_transition_matrix) { // auto *sim = prepareSimulation(); // auto *qubit = new StatQubitTarget{}; @@ -128,17 +147,22 @@ class StatQubitTarget : public StationaryQubit { // ASSERT_EQ(mat.row(6), row6); // } +TEST_F(StatQubitTest, init) { + auto *backend_qubit = new MockBackendQubit(); + auto *config = new IConfiguration(); + EXPECT_CALL(*backend, getDefaultConfiguration()).WillOnce(Return(ByMove(std::unique_ptr(config)))); + EXPECT_CALL(*backend, getQubit(NotNull(), NotNull())).WillOnce(Return(backend_qubit)); + EXPECT_CALL(*backend_qubit, setFree()).WillOnce(Return()); + qubit->callInitialize(); + delete backend_qubit; +} + // TEST(StatQubitTest, setFree) { // auto *sim = prepareSimulation(); // auto *qubit = new StatQubitTarget{}; // sim->registerComponent(qubit); // qubit->fillParams(); // qubit->callInitialize(); -// qubit->par("GOD_Xerror") = true; -// qubit->par("GOD_Zerror") = true; -// qubit->par("GOD_EXerror") = true; -// qubit->par("GOD_REerror") = true; -// qubit->par("GOD_CMerror") = true; // qubit->setFree(true); // EXPECT_EQ(qubit->updated_time, simTime()); @@ -148,12 +172,6 @@ class StatQubitTarget : public StationaryQubit { // qubit->setFree(true); // EXPECT_EQ(qubit->updated_time, simTime()); -// // check the qubit reset properly -// EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); // } // TEST(StatQubitTest, setFreeUpdatesTime) { diff --git a/quisp/test_utils/mock_backends/MockQuantumBackend.h b/quisp/test_utils/mock_backends/MockQuantumBackend.h index 43b1f21bd..cc4e8493f 100644 --- a/quisp/test_utils/mock_backends/MockQuantumBackend.h +++ b/quisp/test_utils/mock_backends/MockQuantumBackend.h @@ -16,5 +16,6 @@ class MockQuantumBackend : public IQuantumBackend { MOCK_METHOD(IBackendQubit *, getQubit, (const IQubitId *, std::unique_ptr configuration), (override)); MOCK_METHOD(const SimTime &, getSimTime, (), (override)); MOCK_METHOD(void, setSimTime, (SimTime time), (override)); + MOCK_METHOD(std::unique_ptr, getDefaultConfiguration, (), (const, override)); }; } // namespace quisp_test::mock_backends From d75980c73cd6139570b49f48c3e379ae8a85af4e Mon Sep 17 00:00:00 2001 From: zigen Date: Wed, 13 Apr 2022 15:29:32 +0900 Subject: [PATCH 13/43] overwrite backend qubit config with StationaryQubit params and renormalize ned params as done in PR#451 --- quisp/modules/Backend/Backend.cc | 56 ++++++------- quisp/modules/Backend/Backend.ned | 42 +++++++++- .../QNIC/StationaryQubit/StationaryQubit.cc | 78 +++++++++---------- .../QNIC/StationaryQubit/StationaryQubit.h | 9 ++- .../QNIC/StationaryQubit/StationaryQubit.ned | 38 +++------ 5 files changed, 125 insertions(+), 98 deletions(-) diff --git a/quisp/modules/Backend/Backend.cc b/quisp/modules/Backend/Backend.cc index 66e33e9c4..a776184c4 100644 --- a/quisp/modules/Backend/Backend.cc +++ b/quisp/modules/Backend/Backend.cc @@ -17,39 +17,39 @@ void BackendContainer::initialize() { void BackendContainer::configureErrorTrackingBackend() { auto conf = std::make_unique(); - conf->measurement_x_err_rate = par("Measurement_X_error_ratio").doubleValue(); - conf->measurement_y_err_rate = par("Measurement_Y_error_ratio").doubleValue(); - conf->measurement_z_err_rate = par("Measurement_Z_error_ratio").doubleValue(); + conf->measurement_x_err_rate = par("x_measurement_error_rate").doubleValue(); + conf->measurement_y_err_rate = par("y_measurement_error_rate").doubleValue(); + conf->measurement_z_err_rate = par("z_measurement_error_rate").doubleValue(); - conf->h_gate_err_rate = par("Hgate_error_rate").doubleValue(); - conf->h_gate_x_err_ratio = par("Hgate_X_error_ratio").doubleValue(); - conf->h_gate_y_err_ratio = par("Hgate_Y_error_ratio").doubleValue(); - conf->h_gate_z_err_ratio = par("Hgate_Z_error_ratio").doubleValue(); + conf->h_gate_err_rate = par("h_gate_error_rate").doubleValue(); + conf->h_gate_x_err_ratio = par("h_gate_X_error_ratio").doubleValue(); + conf->h_gate_y_err_ratio = par("h_gate_Y_error_ratio").doubleValue(); + conf->h_gate_z_err_ratio = par("h_gate_Z_error_ratio").doubleValue(); - conf->x_gate_err_rate = par("Xgate_error_rate").doubleValue(); - conf->x_gate_x_err_ratio = par("Xgate_X_error_ratio").doubleValue(); - conf->x_gate_y_err_ratio = par("Xgate_Y_error_ratio").doubleValue(); - conf->x_gate_z_err_ratio = par("Xgate_Z_error_ratio").doubleValue(); + conf->x_gate_err_rate = par("x_gate_error_rate").doubleValue(); + conf->x_gate_x_err_ratio = par("x_gate_x_error_ratio").doubleValue(); + conf->x_gate_y_err_ratio = par("x_gate_y_error_ratio").doubleValue(); + conf->x_gate_z_err_ratio = par("x_gate_z_error_ratio").doubleValue(); - conf->z_gate_err_rate = par("Zgate_error_rate").doubleValue(); - conf->z_gate_x_err_ratio = par("Zgate_X_error_ratio").doubleValue(); - conf->z_gate_y_err_ratio = par("Zgate_Y_error_ratio").doubleValue(); - conf->z_gate_z_err_ratio = par("Zgate_Z_error_ratio").doubleValue(); + conf->z_gate_err_rate = par("z_gate_error_rate").doubleValue(); + conf->z_gate_x_err_ratio = par("z_gate_x_error_ratio").doubleValue(); + conf->z_gate_y_err_ratio = par("z_gate_y_error_ratio").doubleValue(); + conf->z_gate_z_err_ratio = par("z_gate_z_error_ratio").doubleValue(); - conf->cnot_gate_err_rate = par("CNOTgate_error_rate").doubleValue(); - conf->cnot_gate_iz_err_ratio = par("CNOTgate_IZ_error_ratio").doubleValue(); - conf->cnot_gate_zi_err_ratio = par("CNOTgate_ZI_error_ratio").doubleValue(); - conf->cnot_gate_zz_err_ratio = par("CNOTgate_ZZ_error_ratio").doubleValue(); - conf->cnot_gate_ix_err_ratio = par("CNOTgate_IX_error_ratio").doubleValue(); - conf->cnot_gate_xi_err_ratio = par("CNOTgate_XI_error_ratio").doubleValue(); - conf->cnot_gate_xx_err_ratio = par("CNOTgate_XX_error_ratio").doubleValue(); - conf->cnot_gate_iy_err_ratio = par("CNOTgate_IY_error_ratio").doubleValue(); - conf->cnot_gate_yi_err_ratio = par("CNOTgate_YI_error_ratio").doubleValue(); - conf->cnot_gate_yy_err_ratio = par("CNOTgate_YY_error_ratio").doubleValue(); + conf->cnot_gate_err_rate = par("cnot_gate_error_rate").doubleValue(); + conf->cnot_gate_iz_err_ratio = par("cnot_gate_iz_error_ratio").doubleValue(); + conf->cnot_gate_zi_err_ratio = par("cnot_gate_zi_error_ratio").doubleValue(); + conf->cnot_gate_zz_err_ratio = par("cnot_gate_zz_error_ratio").doubleValue(); + conf->cnot_gate_ix_err_ratio = par("cnot_gate_ix_error_ratio").doubleValue(); + conf->cnot_gate_xi_err_ratio = par("cnot_gate_xi_error_ratio").doubleValue(); + conf->cnot_gate_xx_err_ratio = par("cnot_gate_xx_error_ratio").doubleValue(); + conf->cnot_gate_iy_err_ratio = par("cnot_gate_iy_error_ratio").doubleValue(); + conf->cnot_gate_yi_err_ratio = par("cnot_gate_yi_error_ratio").doubleValue(); + conf->cnot_gate_yy_err_ratio = par("cnot_gate_yy_error_ratio").doubleValue(); - conf->memory_x_err_rate = par("memory_X_error_rate").doubleValue(); - conf->memory_y_err_rate = par("memory_Y_error_rate").doubleValue(); - conf->memory_z_err_rate = par("memory_Z_error_rate").doubleValue(); + conf->memory_x_err_rate = par("memory_x_error_rate").doubleValue(); + conf->memory_y_err_rate = par("memory_y_error_rate").doubleValue(); + conf->memory_z_err_rate = par("memory_z_error_rate").doubleValue(); conf->memory_excitation_rate = par("memory_energy_excitation_rate").doubleValue(); conf->memory_relaxation_rate = par("memory_energy_relaxation_rate").doubleValue(); conf->memory_completely_mixed_rate = par("memory_completely_mixed_rate").doubleValue(); diff --git a/quisp/modules/Backend/Backend.ned b/quisp/modules/Backend/Backend.ned index 4edf2d232..3bbf4cf36 100644 --- a/quisp/modules/Backend/Backend.ned +++ b/quisp/modules/Backend/Backend.ned @@ -6,5 +6,45 @@ simple Backend parameters: @class(BackendContainer); @display("p=30,40;"); - string backend_type = default("ErrorTrackingBackend"); + string backendType = default("ErrorTrackingBackend"); + + // ErrorTracking Backend Configurations + // characteristics of the hardware + double memory_error_rate = default(0); + double memory_z_error_rate = default(1); + double memory_x_error_rate = default(1); + double memory_y_error_rate = default(1); + double memory_energy_excitation_rate = default(1); + double memory_energy_relaxation_rate = default(1); + double memory_completely_mixed_rate = default(1); + + double h_gate_error_rate = default(0); + double h_gate_x_error_ratio = default(1); + double h_gate_y_error_ratio = default(1); + double h_gate_z_error_ratio = default(1); + + double x_gate_error_rate = default(0); + double x_gate_x_error_ratio = default(1); + double x_gate_y_error_ratio = default(1); + double x_gate_z_error_ratio = default(1); + + double z_gate_error_rate = default(0); + double z_gate_x_error_ratio = default(1); + double z_gate_y_error_ratio = default(1); + double z_gate_z_error_ratio = default(1); + + double cnot_gate_error_rate = default(0); + double cnot_gate_iz_error_ratio = default(1); + double cnot_gate_zi_error_ratio = default(1); + double cnot_gate_zz_error_ratio = default(1); + double cnot_gate_ix_error_ratio = default(1); + double cnot_gate_xi_error_ratio = default(1); + double cnot_gate_xx_error_ratio = default(1); + double cnot_gate_iy_error_ratio = default(1); + double cnot_gate_yi_error_ratio = default(1); + double cnot_gate_yy_error_ratio = default(1); + + double x_measurement_error_rate = default(0); + double y_measurement_error_rate = default(0); + double z_measurement_error_rate = default(0); } diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index aa20b3d94..d281ed79b 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -61,7 +61,7 @@ void StationaryQubit::initialize() { vertex_operator = CliffordOperator::H; backend = provider.getQuantumBackend(); - auto config = prepareBackendQubitConfiguration(); + auto config = prepareBackendQubitConfiguration(par("overwrite_backend_qubit_config").boolValue()); qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationaryQubit_address), std::move(config)); if (qubit_ref == nullptr) throw std::runtime_error("qubit_ref nullptr error"); setFree(false); @@ -72,49 +72,43 @@ void StationaryQubit::initialize() { WATCH(is_busy); } -void StationaryQubit::tryToAssignParDouble(double &field, const char *par_name) { - int par_index = findPar(par_name); - if (par_index == -1) return; - field = par(par_index).doubleValue(); -} - -std::unique_ptr StationaryQubit::prepareBackendQubitConfiguration() { +std::unique_ptr StationaryQubit::prepareBackendQubitConfiguration(bool overwrite) { auto conf = backend->getDefaultConfiguration(); + if (!overwrite) return conf; if (auto et_conf = dynamic_cast(conf.get())) { - tryToAssignParDouble(et_conf->measurement_x_err_rate, "Measurement_X_error_ratio"); - et_conf->measurement_x_err_rate = par("Measurement_X_error_ratio").doubleValue(); - et_conf->measurement_y_err_rate = par("Measurement_Y_error_ratio").doubleValue(); - et_conf->measurement_z_err_rate = par("Measurement_Z_error_ratio").doubleValue(); - - et_conf->h_gate_err_rate = par("Hgate_error_rate").doubleValue(); - et_conf->h_gate_x_err_ratio = par("Hgate_X_error_ratio").doubleValue(); - et_conf->h_gate_y_err_ratio = par("Hgate_Y_error_ratio").doubleValue(); - et_conf->h_gate_z_err_ratio = par("Hgate_Z_error_ratio").doubleValue(); - - et_conf->x_gate_err_rate = par("Xgate_error_rate").doubleValue(); - et_conf->x_gate_x_err_ratio = par("Xgate_X_error_ratio").doubleValue(); - et_conf->x_gate_y_err_ratio = par("Xgate_Y_error_ratio").doubleValue(); - et_conf->x_gate_z_err_ratio = par("Xgate_Z_error_ratio").doubleValue(); - - et_conf->z_gate_err_rate = par("Zgate_error_rate").doubleValue(); - et_conf->z_gate_x_err_ratio = par("Zgate_X_error_ratio").doubleValue(); - et_conf->z_gate_y_err_ratio = par("Zgate_Y_error_ratio").doubleValue(); - et_conf->z_gate_z_err_ratio = par("Zgate_Z_error_ratio").doubleValue(); - - et_conf->cnot_gate_err_rate = par("CNOTgate_error_rate").doubleValue(); - et_conf->cnot_gate_iz_err_ratio = par("CNOTgate_IZ_error_ratio").doubleValue(); - et_conf->cnot_gate_zi_err_ratio = par("CNOTgate_ZI_error_ratio").doubleValue(); - et_conf->cnot_gate_zz_err_ratio = par("CNOTgate_ZZ_error_ratio").doubleValue(); - et_conf->cnot_gate_ix_err_ratio = par("CNOTgate_IX_error_ratio").doubleValue(); - et_conf->cnot_gate_xi_err_ratio = par("CNOTgate_XI_error_ratio").doubleValue(); - et_conf->cnot_gate_xx_err_ratio = par("CNOTgate_XX_error_ratio").doubleValue(); - et_conf->cnot_gate_iy_err_ratio = par("CNOTgate_IY_error_ratio").doubleValue(); - et_conf->cnot_gate_yi_err_ratio = par("CNOTgate_YI_error_ratio").doubleValue(); - et_conf->cnot_gate_yy_err_ratio = par("CNOTgate_YY_error_ratio").doubleValue(); - - et_conf->memory_x_err_rate = par("memory_X_error_rate").doubleValue(); - et_conf->memory_y_err_rate = par("memory_Y_error_rate").doubleValue(); - et_conf->memory_z_err_rate = par("memory_Z_error_rate").doubleValue(); + et_conf->measurement_x_err_rate = par("x_measurement_error_rate").doubleValue(); + et_conf->measurement_y_err_rate = par("y_measurement_error_rate").doubleValue(); + et_conf->measurement_z_err_rate = par("z_measurement_error_rate").doubleValue(); + + et_conf->h_gate_err_rate = par("h_gate_error_rate").doubleValue(); + et_conf->h_gate_x_err_ratio = par("h_gate_x_error_ratio").doubleValue(); + et_conf->h_gate_y_err_ratio = par("h_gate_y_error_ratio").doubleValue(); + et_conf->h_gate_z_err_ratio = par("h_gate_z_error_ratio").doubleValue(); + + et_conf->x_gate_err_rate = par("x_gate_error_rate").doubleValue(); + et_conf->x_gate_x_err_ratio = par("x_gate_x_error_ratio").doubleValue(); + et_conf->x_gate_y_err_ratio = par("x_gate_y_error_ratio").doubleValue(); + et_conf->x_gate_z_err_ratio = par("x_gate_z_error_ratio").doubleValue(); + + et_conf->z_gate_err_rate = par("z_gate_error_rate").doubleValue(); + et_conf->z_gate_x_err_ratio = par("z_gate_x_error_ratio").doubleValue(); + et_conf->z_gate_y_err_ratio = par("z_gate_y_error_ratio").doubleValue(); + et_conf->z_gate_z_err_ratio = par("z_gate_z_error_ratio").doubleValue(); + + et_conf->cnot_gate_err_rate = par("cnot_gate_error_rate").doubleValue(); + et_conf->cnot_gate_iz_err_ratio = par("cnot_gate_iz_error_ratio").doubleValue(); + et_conf->cnot_gate_zi_err_ratio = par("cnot_gate_zi_error_ratio").doubleValue(); + et_conf->cnot_gate_zz_err_ratio = par("cnot_gate_zz_error_ratio").doubleValue(); + et_conf->cnot_gate_ix_err_ratio = par("cnot_gate_ix_error_ratio").doubleValue(); + et_conf->cnot_gate_xi_err_ratio = par("cnot_gate_xi_error_ratio").doubleValue(); + et_conf->cnot_gate_xx_err_ratio = par("cnot_gate_xx_error_ratio").doubleValue(); + et_conf->cnot_gate_iy_err_ratio = par("cnot_gate_iy_error_ratio").doubleValue(); + et_conf->cnot_gate_yi_err_ratio = par("cnot_gate_yi_error_ratio").doubleValue(); + et_conf->cnot_gate_yy_err_ratio = par("cnot_gate_yy_error_ratio").doubleValue(); + + et_conf->memory_x_err_rate = par("memory_x_error_rate").doubleValue(); + et_conf->memory_y_err_rate = par("memory_y_error_rate").doubleValue(); + et_conf->memory_z_err_rate = par("memory_z_error_rate").doubleValue(); et_conf->memory_excitation_rate = par("memory_energy_excitation_rate").doubleValue(); et_conf->memory_relaxation_rate = par("memory_energy_relaxation_rate").doubleValue(); et_conf->memory_completely_mixed_rate = par("memory_completely_mixed_rate").doubleValue(); diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index bb0b1debc..2851ed203 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -161,7 +161,14 @@ class StationaryQubit : public IStationaryQubit { messages::PhotonicQubit *generateEntangledPhoton(); void setBusy(); Eigen::Matrix2cd getErrorMatrix(StationaryQubit *qubit); - std::unique_ptr prepareBackendQubitConfiguration(); + + /** + * get the default backend configuration from the Bcakend module. + * if overwrite arg is true, collect StationaryQubit's backend qubit config + * and overwrite the default configuration with it. + * if you want to use different qubit configuration, it's useful. + */ + std::unique_ptr prepareBackendQubitConfiguration(bool overwrite); void tryToAssignParDouble(double &field, const char *par_name); // this is for debugging. class internal use only. diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned index 176c3b700..606de5294 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned @@ -28,48 +28,34 @@ simple StationaryQubit double emission_x_error_rate = default(0); double emission_y_error_rate = default(0); - // ZZZ -- these are configured at boot time - // characteristics of the hardware - // could eventually change over time if we model dynamic - // changes to the device - double memory_z_error_rate = default(0); - double memory_x_error_rate = default(0); - double memory_y_error_rate = default(0); - double memory_energy_excitation_rate = default(0); - double memory_energy_relaxation_rate = default(0); - double memory_completely_mixed_rate = default(0); + bool overwrite_backend_qubit_config = default(false); + + // ErrorTracking Backend Qubit Configuration + // if overwrite_backend_qubit_config is true, + // these params overwrite the default configuration at the backend module. + double memory_error_rate = default(0); + double memory_z_error_rate = default(1); + double memory_x_error_rate = default(1); + double memory_y_error_rate = default(1); + double memory_energy_excitation_rate = default(1); + double memory_energy_relaxation_rate = default(1); + double memory_completely_mixed_rate = default(1); - // ZZZ -- these are configured at boot time - // characteristics of the hardware - // could eventually change over time if we model dynamic - // changes to the device double h_gate_error_rate = default(0); double h_gate_x_error_ratio = default(1); double h_gate_y_error_ratio = default(1); double h_gate_z_error_ratio = default(1); - // ZZZ -- these are configured at boot time - // characteristics of the hardware - // could eventually change over time if we model dynamic - // changes to the device double x_gate_error_rate = default(0); double x_gate_x_error_ratio = default(1); double x_gate_y_error_ratio = default(1); double x_gate_z_error_ratio = default(1); - // ZZZ -- these are configured at boot time - // characteristics of the hardware - // could eventually change over time if we model dynamic - // changes to the device double z_gate_error_rate = default(0); double z_gate_x_error_ratio = default(1); double z_gate_y_error_ratio = default(1); double z_gate_z_error_ratio = default(1); - // ZZZ -- these are configured at boot time - // characteristics of the hardware - // could eventually change over time if we model dynamic - // changes to the device double cnot_gate_error_rate = default(0); double cnot_gate_iz_error_ratio = default(1); double cnot_gate_zi_error_ratio = default(1); From a136f1d909807a0282ead35b2f2da77628309343 Mon Sep 17 00:00:00 2001 From: zigen Date: Thu, 14 Apr 2022 00:34:22 +0900 Subject: [PATCH 14/43] fix tests --- quisp/modules/Backend/Backend_test.cc | 57 +++++++++---------- .../StationaryQubit/StationaryQubit_test.cc | 2 + 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/quisp/modules/Backend/Backend_test.cc b/quisp/modules/Backend/Backend_test.cc index b5cc54286..11c239152 100644 --- a/quisp/modules/Backend/Backend_test.cc +++ b/quisp/modules/Backend/Backend_test.cc @@ -22,35 +22,34 @@ class BackendContainerTest : public ::testing::Test { virtual void SetUp() { auto *sim = utils::prepareSimulation(); backend = new BackendContainer(); - setParDouble(backend, "Measurement_error_rate", .01); - setParDouble(backend, "Measurement_X_error_ratio", .02); - setParDouble(backend, "Measurement_Y_error_ratio", .03); - setParDouble(backend, "Measurement_Z_error_ratio", .04); - setParDouble(backend, "Hgate_error_rate", .05); - setParDouble(backend, "Hgate_X_error_ratio", .06); - setParDouble(backend, "Hgate_Y_error_ratio", .07); - setParDouble(backend, "Hgate_Z_error_ratio", .08); - setParDouble(backend, "Xgate_error_rate", .06); - setParDouble(backend, "Xgate_X_error_ratio", .07); - setParDouble(backend, "Xgate_Y_error_ratio", .08); - setParDouble(backend, "Xgate_Z_error_ratio", .09); - setParDouble(backend, "Zgate_error_rate", .10); - setParDouble(backend, "Zgate_X_error_ratio", .11); - setParDouble(backend, "Zgate_Y_error_ratio", .12); - setParDouble(backend, "Zgate_Z_error_ratio", .13); - setParDouble(backend, "CNOTgate_error_rate", .14); - setParDouble(backend, "CNOTgate_IX_error_ratio", .15); - setParDouble(backend, "CNOTgate_XI_error_ratio", .16); - setParDouble(backend, "CNOTgate_XX_error_ratio", .17); - setParDouble(backend, "CNOTgate_IY_error_ratio", .18); - setParDouble(backend, "CNOTgate_YI_error_ratio", .19); - setParDouble(backend, "CNOTgate_YY_error_ratio", .20); - setParDouble(backend, "CNOTgate_IZ_error_ratio", .21); - setParDouble(backend, "CNOTgate_ZI_error_ratio", .22); - setParDouble(backend, "CNOTgate_ZZ_error_ratio", .23); - setParDouble(backend, "memory_X_error_rate", .24); - setParDouble(backend, "memory_Y_error_rate", .25); - setParDouble(backend, "memory_Z_error_rate", .26); + setParDouble(backend, "x_measurement_error_rate", .02); + setParDouble(backend, "y_measurement_error_rate", .03); + setParDouble(backend, "z_measurement_error_rate", .04); + setParDouble(backend, "h_gate_error_rate", .05); + setParDouble(backend, "h_gate_x_error_ratio", .06); + setParDouble(backend, "h_gate_y_error_ratio", .07); + setParDouble(backend, "h_gate_z_error_ratio", .08); + setParDouble(backend, "x_gate_error_rate", .06); + setParDouble(backend, "x_gate_x_error_ratio", .07); + setParDouble(backend, "x_gate_y_error_ratio", .08); + setParDouble(backend, "x_gate_z_error_ratio", .09); + setParDouble(backend, "z_gate_error_rate", .10); + setParDouble(backend, "z_gate_x_error_ratio", .11); + setParDouble(backend, "z_gate_y_error_ratio", .12); + setParDouble(backend, "z_gate_z_error_ratio", .13); + setParDouble(backend, "cnot_gate_error_rate", .14); + setParDouble(backend, "cnot_gate_ix_error_ratio", .15); + setParDouble(backend, "cnot_gate_xi_error_ratio", .16); + setParDouble(backend, "cnot_gate_xx_error_ratio", .17); + setParDouble(backend, "cnot_gate_iy_error_ratio", .18); + setParDouble(backend, "cnot_gate_yi_error_ratio", .19); + setParDouble(backend, "cnot_gate_yy_error_ratio", .20); + setParDouble(backend, "cnot_gate_iz_error_ratio", .21); + setParDouble(backend, "cnot_gate_zi_error_ratio", .22); + setParDouble(backend, "cnot_gate_zz_error_ratio", .23); + setParDouble(backend, "memory_x_error_rate", .24); + setParDouble(backend, "memory_y_error_rate", .25); + setParDouble(backend, "memory_z_error_rate", .26); setParDouble(backend, "memory_energy_excitation_rate", .27); setParDouble(backend, "memory_energy_relaxation_rate", .28); setParDouble(backend, "memory_completely_mixed_rate", .29); diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 8a37127f5..3cc1c7d43 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -7,6 +7,7 @@ #include #include "backends/interfaces/IConfiguration.h" #include "backends/interfaces/IQuantumBackend.h" +#include "test_utils/UtilFunctions.h" #include "test_utils/mock_backends/MockQuantumBackend.h" using namespace testing; @@ -84,6 +85,7 @@ class StatQubitTarget : public StationaryQubit { setParInt(this, "qnic_type", 0); setParInt(this, "qnic_index", 0); setParDouble(this, "emission_jittering_standard_deviation", 0.5); + setParBool(this, "overwrite_backend_qubit_config", false); } }; From 194f740af821fb79187e072afc2b68d5016ba058 Mon Sep 17 00:00:00 2001 From: zigen Date: Fri, 15 Apr 2022 20:20:05 +0900 Subject: [PATCH 15/43] add more EtBackend Test --- quisp/backends/ErrorTracking/Backend.cc | 14 +- quisp/backends/ErrorTracking/Backend_test.cc | 121 +++++++++++++++++- quisp/backends/ErrorTracking/Qubit.cc | 66 +++++----- .../ErrorTracking/Qubit_gate_error_test.cc | 4 +- quisp/backends/ErrorTracking/test.h | 4 +- quisp/backends/interfaces/IQuantumBackend.h | 1 - quisp/modules/Backend/Backend_test.cc | 3 + 7 files changed, 172 insertions(+), 41 deletions(-) diff --git a/quisp/backends/ErrorTracking/Backend.cc b/quisp/backends/ErrorTracking/Backend.cc index 6771a348f..5edf6a47d 100644 --- a/quisp/backends/ErrorTracking/Backend.cc +++ b/quisp/backends/ErrorTracking/Backend.cc @@ -1,8 +1,10 @@ #include "Backend.h" +#include #include #include #include "Qubit.h" #include "backends/ErrorTracking/Configuration.h" +#include "backends/interfaces/IConfiguration.h" namespace quisp::backends::error_tracking { using error_tracking::ErrorTrackingQubit; @@ -18,13 +20,23 @@ ErrorTrackingBackend::~ErrorTrackingBackend() { } } -IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id, std::unique_ptr configuration) { +IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id, std::unique_ptr conf) { auto qubit = qubits.find(id); if (qubit != qubits.cend()) { return qubit->second.get(); } auto original_qubit = std::make_unique(id, this); + + IConfiguration* raw_conf = conf.release(); + ErrorTrackingConfiguration* et_conf = dynamic_cast(raw_conf); + + if (et_conf == nullptr) { + delete raw_conf; + throw std::runtime_error("ErrorTrackingBackend::getQubit: failed to cast. got invalid configulation."); + } + + original_qubit->configure(std::unique_ptr(et_conf)); auto* qubit_ptr = original_qubit.get(); qubits.insert({id, std::move(original_qubit)}); return qubit_ptr; diff --git a/quisp/backends/ErrorTracking/Backend_test.cc b/quisp/backends/ErrorTracking/Backend_test.cc index 39de2a92f..92372b3be 100644 --- a/quisp/backends/ErrorTracking/Backend_test.cc +++ b/quisp/backends/ErrorTracking/Backend_test.cc @@ -4,6 +4,8 @@ #include #include "../interfaces/IRandomNumberGenerator.h" #include "Configuration.h" +#include "Qubit.h" +#include "backends/interfaces/IConfiguration.h" #include "test.h" namespace { @@ -11,15 +13,52 @@ using namespace quisp::backends::error_tracking; using namespace quisp_test::backends; using namespace omnetpp; +class TestEtQubit : public ErrorTrackingQubit { + public: + using ErrorTrackingQubit::addErrorX; + using ErrorTrackingQubit::addErrorZ; + using ErrorTrackingQubit::applyMemoryError; + using ErrorTrackingQubit::applySingleQubitGateError; + using ErrorTrackingQubit::applyTwoQubitGateError; + using ErrorTrackingQubit::correlationMeasureX; + using ErrorTrackingQubit::correlationMeasureY; + using ErrorTrackingQubit::correlationMeasureZ; + using ErrorTrackingQubit::entangled_partner; + using ErrorTrackingQubit::gate_err_cnot; + using ErrorTrackingQubit::gate_err_h; + using ErrorTrackingQubit::gate_err_x; + using ErrorTrackingQubit::gate_err_z; + using ErrorTrackingQubit::getErrorMatrix; + using ErrorTrackingQubit::getQuantumState; + using ErrorTrackingQubit::has_completely_mixed_error; + using ErrorTrackingQubit::has_excitation_error; + using ErrorTrackingQubit::has_relaxation_error; + using ErrorTrackingQubit::has_x_error; + using ErrorTrackingQubit::has_z_error; + using ErrorTrackingQubit::localMeasureX; + using ErrorTrackingQubit::localMeasureZ; + using ErrorTrackingQubit::measureDensityIndependent; + using ErrorTrackingQubit::measurement_err; + using ErrorTrackingQubit::memory_err; + using ErrorTrackingQubit::setMemoryErrorRates; + using ErrorTrackingQubit::updated_time; +}; + +class EtBackend : public ErrorTrackingBackend { + public: + using ErrorTrackingBackend::qubits; + EtBackend(std::unique_ptr rng, std::unique_ptr config) : ErrorTrackingBackend(std::move(rng), std::move(config)) {} +}; + class EtBackendTest : public ::testing::Test { protected: virtual void SetUp() { SimTime::setScaleExp(-9); rng = new TestRNG(); - backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); + backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); } TestRNG* rng; - std::unique_ptr backend; + std::unique_ptr backend; }; TEST_F(EtBackendTest, getQubit) { @@ -36,4 +75,82 @@ TEST_F(EtBackendTest, getQubit) { EXPECT_EQ(same_qubit, qubit); } +TEST_F(EtBackendTest, getQubitWithConfiguration) { + auto conf = new ErrorTrackingConfiguration; + conf->cnot_gate_err_rate = 0.75; + conf->cnot_gate_ix_err_ratio = 0.75 / 9.; + conf->cnot_gate_xi_err_ratio = 0.75 / 9.; + conf->cnot_gate_xx_err_ratio = 0.75 / 9.; + conf->cnot_gate_iy_err_ratio = 0.75 / 9.; + conf->cnot_gate_yi_err_ratio = 0.75 / 9.; + conf->cnot_gate_yy_err_ratio = 0.75 / 9.; + conf->cnot_gate_iz_err_ratio = 0.75 / 9.; + conf->cnot_gate_zi_err_ratio = 0.75 / 9.; + conf->cnot_gate_zz_err_ratio = 0.75 / 9.; + conf->h_gate_err_rate = 1.0; + conf->h_gate_x_err_ratio = 1. / 3.; + conf->h_gate_y_err_ratio = 1. / 3.; + conf->h_gate_z_err_ratio = 1. / 3.; + conf->x_gate_err_rate = 0.5; + conf->x_gate_x_err_ratio = 0.5 / 3.; + conf->x_gate_y_err_ratio = 0.5 / 3.; + conf->x_gate_z_err_ratio = 0.5 / 3.; + conf->z_gate_err_rate = 0.25; + conf->z_gate_x_err_ratio = 0.25 / 3.; + conf->z_gate_y_err_ratio = 0.25 / 3.; + conf->z_gate_z_err_ratio = 0.25 / 3.; + conf->measurement_x_err_rate = 0.23; + conf->measurement_y_err_rate = 0.24; + conf->measurement_z_err_rate = 0.25; + conf->memory_x_err_rate = 0.26; + conf->memory_y_err_rate = 0.27; + conf->memory_z_err_rate = 0.28; + conf->memory_relaxation_rate = 0.29; + conf->memory_excitation_rate = 0.30; + conf->memory_completely_mixed_rate = 0.31; + + auto conf2 = std::make_unique(*conf); + + auto* id = new QubitId(123); + EXPECT_EQ(backend->qubits.size(), 0); + auto* qubit = backend->getQubit(id, std::move(conf2)); + EXPECT_EQ(backend->qubits.size(), 1); + EXPECT_EQ(qubit, backend->getQubit(id)); + EXPECT_EQ(backend->qubits.size(), 1); + auto et_qubit = reinterpret_cast(qubit); + + EXPECT_EQ(et_qubit->gate_err_h.x_error_rate, conf->h_gate_x_err_ratio); + EXPECT_EQ(et_qubit->gate_err_h.y_error_rate, conf->h_gate_y_err_ratio); + EXPECT_EQ(et_qubit->gate_err_h.z_error_rate, conf->h_gate_z_err_ratio); + + EXPECT_EQ(et_qubit->gate_err_x.x_error_rate, conf->x_gate_x_err_ratio); + EXPECT_EQ(et_qubit->gate_err_x.y_error_rate, conf->x_gate_y_err_ratio); + EXPECT_EQ(et_qubit->gate_err_x.z_error_rate, conf->x_gate_z_err_ratio); + + EXPECT_EQ(et_qubit->gate_err_z.x_error_rate, conf->z_gate_x_err_ratio); + EXPECT_EQ(et_qubit->gate_err_z.y_error_rate, conf->z_gate_y_err_ratio); + EXPECT_EQ(et_qubit->gate_err_z.z_error_rate, conf->z_gate_z_err_ratio); + + EXPECT_EQ(et_qubit->measurement_err.x_error_rate, conf->measurement_x_err_rate); + EXPECT_EQ(et_qubit->measurement_err.y_error_rate, conf->measurement_y_err_rate); + EXPECT_EQ(et_qubit->measurement_err.z_error_rate, conf->measurement_z_err_rate); + + EXPECT_EQ(et_qubit->memory_err.x_error_rate, conf->memory_x_err_rate); + EXPECT_EQ(et_qubit->memory_err.y_error_rate, conf->memory_y_err_rate); + EXPECT_EQ(et_qubit->memory_err.z_error_rate, conf->memory_z_err_rate); + EXPECT_EQ(et_qubit->memory_err.excitation_error_rate, conf->memory_excitation_rate); + EXPECT_EQ(et_qubit->memory_err.relaxation_error_rate, conf->memory_relaxation_rate); + EXPECT_EQ(et_qubit->memory_err.completely_mixed_rate, conf->memory_completely_mixed_rate); + + EXPECT_EQ(et_qubit->gate_err_cnot.ix_error_rate, conf->cnot_gate_ix_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.xi_error_rate, conf->cnot_gate_xi_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.xx_error_rate, conf->cnot_gate_xx_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.iy_error_rate, conf->cnot_gate_iy_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.yi_error_rate, conf->cnot_gate_yi_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.yy_error_rate, conf->cnot_gate_yy_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.iz_error_rate, conf->cnot_gate_iz_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.zi_error_rate, conf->cnot_gate_zi_err_ratio); + EXPECT_EQ(et_qubit->gate_err_cnot.zz_error_rate, conf->cnot_gate_zz_err_ratio); +} + } // namespace diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index 9bf0ca4e6..664ce4bee 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -482,8 +482,8 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { throw std::runtime_error("Measuring a qubit that is not entangled with another qubit. Probably not what you want! Check whether address for each node is unique!!!"); } MeasurementOperator this_measurement = randomMeasurementBasisSelection(); // Select basis randomly - char Output; - bool Output_is_plus; + char output; + bool output_is_plus; // Add memory error depending on the idle time. If excited/relaxed, this will immediately break entanglement, leaving the other qubit as completely mixed. applyMemoryError(); @@ -503,20 +503,20 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { } /*-For debugging-*/ - char GOD_state = 'F'; // Completely mixed + char god_state = 'F'; // Completely mixed if (has_excitation_error) - GOD_state = 'E'; + god_state = 'E'; else if (has_excitation_error /* XXX: this might be relaxation error? */) - GOD_state = 'R'; + god_state = 'R'; else if (has_completely_mixed_error) - GOD_state = 'C'; + god_state = 'C'; else if (!has_x_error && has_z_error) // To check stabilizers.... - GOD_state = 'Z'; + god_state = 'Z'; else if (has_x_error && !has_z_error) - GOD_state = 'X'; + god_state = 'X'; else if (has_x_error && has_z_error) - GOD_state = 'Y'; + god_state = 'Y'; /*---------------*/ @@ -535,29 +535,29 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { if (density_matrix_collapsed(0, 0).real() == -111) { // We always need some kind of density matrix inside this if statement. throw std::runtime_error("Single qubit density matrix not stored properly after partner's measurement, excitation/relaxation error."); } - bool Xerr = has_x_error; - bool Zerr = has_z_error; + bool x_err = has_x_error; + bool z_err = has_z_error; // This qubit's density matrix was created when the partner measured his own. // Because this qubit can be measured after that, we need to update the stored density matrix according to new errors occurred due to memory error. - if (Xerr != god_dm_has_x_error) { // Another X error to the dm. + if (x_err != god_dm_has_x_error) { // Another X error to the dm. density_matrix_collapsed = pauli.X * density_matrix_collapsed * pauli.X.adjoint(); } - if (Zerr != god_dm_has_z_error) { // Another Z error to the dm. + if (z_err != god_dm_has_z_error) { // Another Z error to the dm. density_matrix_collapsed = pauli.Z * density_matrix_collapsed * pauli.Z.adjoint(); } // std::cout<<"Not entangled anymore. Density matrix is "<dblrand(); - if (dbl < Prob_plus.real()) { - Output = '+'; - Output_is_plus = true; + if (dbl < prob_plus.real()) { + output = '+'; + output_is_plus = true; } else { - Output = '-'; - Output_is_plus = false; + output = '-'; + output_is_plus = false; } // std::cout<<"\n This qubit was "<partner_measured && !has_completely_mixed_error && !(has_relaxation_error || has_excitation_error) && this->entangled_partner != nullptr) { @@ -565,27 +565,27 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { QuantumState current_state = getQuantumState(); std::cout << "Current entangled state is " << current_state.state_in_ket << "\n"; - bool Xerr = god_dm_has_x_error; - bool Zerr = god_dm_has_z_error; + bool x_err = god_dm_has_x_error; + bool z_err = god_dm_has_z_error; // std::cout<<"Entangled state is "<dblrand(); Vector2cd ms; - if (dbl < Prob_plus.real()) { // Measurement output was plus - Output = '+'; + if (dbl < prob_plus.real()) { // Measurement output was plus + output = '+'; ms = this_measurement.plus_ket; - Output_is_plus = true; + output_is_plus = true; } else { // Otherwise, it was negative. - Output = '-'; + output = '-'; ms = this_measurement.minus_ket; - Output_is_plus = false; + output_is_plus = false; } // Now we have to calculate the density matrix of a single qubit that used to be entangled with this. Matrix2cd partners_dm, normalized_partners_dm; @@ -595,7 +595,7 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { std::cout << "kroneckerProduct(ms.adjoint(),meas_op.identity).eval() = " << kroneckerProduct(ms.adjoint(), measurement_op.identity).eval() << "\n"; std::cout << "dm = " << current_state.state_in_density_matrix << "\n"; std::cout << "State was " << kroneckerProduct(ms.adjoint(), measurement_op.identity).eval() * current_state.state_in_density_matrix << "\n"; - std::cout << "\n This qubit was " << this_measurement.basis << "(" << Output << "). Partner's dm is now = " << normalized_partners_dm << "\n"; + std::cout << "\n This qubit was " << this_measurement.basis << "(" << output << "). Partner's dm is now = " << normalized_partners_dm << "\n"; entangled_partner->density_matrix_collapsed = normalized_partners_dm; // We actually do not need this as long as deleting entangled_partner completely is totally fine. @@ -618,13 +618,13 @@ MeasurementOutcome ErrorTrackingQubit::measureDensityIndependent() { if ((this_measurement.basis == measurement_op.x_basis.basis && rand_num < measurement_err.x_error_rate) || (this_measurement.basis == measurement_op.y_basis.basis && rand_num < measurement_err.y_error_rate) || (this_measurement.basis == measurement_op.z_basis.basis && rand_num < measurement_err.z_error_rate)) { - Output_is_plus = !Output_is_plus; + output_is_plus = !output_is_plus; } MeasurementOutcome o; o.basis = this_measurement.basis; - o.outcome_is_plus = Output_is_plus; - o.GOD_clean = GOD_state; + o.outcome_is_plus = output_is_plus; + o.GOD_clean = god_state; return o; } diff --git a/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc b/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc index fcc104607..621415f8c 100644 --- a/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc @@ -16,9 +16,9 @@ class EtQubitGateErrorTest : public ::testing::Test { rng = new TestRNG(); rng->double_value = .0; backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); - qubit = dynamic_cast(backend->getQubit(new QubitId(0))); + qubit = dynamic_cast(backend->getQubit(0)); if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); - qubit2 = dynamic_cast(backend->getQubit(new QubitId(1))); + qubit2 = dynamic_cast(backend->getQubit(1)); if (qubit2 == nullptr) throw std::runtime_error("Qubit is nullptr"); backend->setSimTime(SimTime(1, SIMTIME_US)); fillParams(qubit); diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index 2ac430dbd..a41b950ef 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -79,8 +79,8 @@ class Backend : public ErrorTrackingBackend { public: using ErrorTrackingBackend::qubits; Backend(std::unique_ptr rng, std::unique_ptr config) : ErrorTrackingBackend(std::move(rng), std::move(config)) {} - IQubit* getQubit(int id) { return getQubit(new QubitId(id)); } - IQubit* getQubit(const IQubitId* id) override { + IQubit* getQubit(int id) { return this->getQubitInternal(new QubitId(id)); } + IQubit* getQubitInternal(const IQubitId* id) { auto qubit = qubits.find(id); if (qubit != qubits.cend()) { diff --git a/quisp/backends/interfaces/IQuantumBackend.h b/quisp/backends/interfaces/IQuantumBackend.h index 07a443c92..a69775d7f 100644 --- a/quisp/backends/interfaces/IQuantumBackend.h +++ b/quisp/backends/interfaces/IQuantumBackend.h @@ -9,7 +9,6 @@ namespace quisp::backends::abstract { using omnetpp::SimTime; using omnetpp::SimTimeUnit; class IQubit; -class IConfigurationCollector; /** * @brief The abstract interface for a quantum backend. diff --git a/quisp/modules/Backend/Backend_test.cc b/quisp/modules/Backend/Backend_test.cc index 11c239152..9434552d5 100644 --- a/quisp/modules/Backend/Backend_test.cc +++ b/quisp/modules/Backend/Backend_test.cc @@ -55,6 +55,9 @@ class BackendContainerTest : public ::testing::Test { setParDouble(backend, "memory_completely_mixed_rate", .29); sim->registerComponent(backend); } + virtual void TearDown() {} + + // managed by cSimulation, so we don't need to use unique_ptr nor delete manually. BackendContainer *backend; }; From 75b8ea42a78a9f3d0822ed1480c04d7a086d7f9a Mon Sep 17 00:00:00 2001 From: zigen Date: Sat, 16 Apr 2022 14:46:51 +0900 Subject: [PATCH 16/43] add QuantumBackend Test --- quisp/backends/ErrorTracking/Backend.cc | 12 +----------- quisp/backends/ErrorTracking/Backend_test.cc | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/quisp/backends/ErrorTracking/Backend.cc b/quisp/backends/ErrorTracking/Backend.cc index 5edf6a47d..e3b461540 100644 --- a/quisp/backends/ErrorTracking/Backend.cc +++ b/quisp/backends/ErrorTracking/Backend.cc @@ -42,17 +42,7 @@ IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id, std::unique_ptrsecond.get(); - } - auto original_qubit = std::make_unique(id, this); - auto* qubit_ptr = original_qubit.get(); - qubits.insert({id, std::move(original_qubit)}); - return qubit_ptr; -} +IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id) { return getQubit(id, getDefaultConfiguration()); } std::unique_ptr ErrorTrackingBackend::getDefaultConfiguration() const { // copy the default backend configuration for each qubit return std::make_unique(*config.get()); diff --git a/quisp/backends/ErrorTracking/Backend_test.cc b/quisp/backends/ErrorTracking/Backend_test.cc index 92372b3be..1705d9991 100644 --- a/quisp/backends/ErrorTracking/Backend_test.cc +++ b/quisp/backends/ErrorTracking/Backend_test.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "../interfaces/IRandomNumberGenerator.h" #include "Configuration.h" #include "Qubit.h" @@ -75,6 +76,21 @@ TEST_F(EtBackendTest, getQubit) { EXPECT_EQ(same_qubit, qubit); } +TEST_F(EtBackendTest, getQubitTwice) { + auto* id = new QubitId(3); + auto* qubit1 = backend->getQubit(id); + auto* qubit2 = backend->getQubit(id); + EXPECT_NE(qubit1, nullptr); + EXPECT_NE(qubit2, nullptr); + EXPECT_EQ(qubit1, qubit2); +} + +TEST_F(EtBackendTest, getQubitWithInvalidConfiguration) { + auto conf = new IConfiguration; + auto* id = new QubitId(4); + ASSERT_THROW({ backend->getQubit(id, std::unique_ptr(conf)); }, std::runtime_error); +} + TEST_F(EtBackendTest, getQubitWithConfiguration) { auto conf = new ErrorTrackingConfiguration; conf->cnot_gate_err_rate = 0.75; From f7450d37951342eda80aef46daeab34f5e06eee0 Mon Sep 17 00:00:00 2001 From: zigen Date: Sat, 16 Apr 2022 15:41:22 +0900 Subject: [PATCH 17/43] add EtQubit tests and remove unused StatQubit tests --- quisp/backends/ErrorTracking/Qubit.cc | 1 + quisp/backends/ErrorTracking/Qubit_test.cc | 126 ++++ quisp/backends/ErrorTracking/test.h | 1 + .../StationaryQubit_gate_error_test.cc | 597 ----------------- .../StationaryQubit_measurement_test.cc | 609 ------------------ .../StationaryQubit_memory_error_test.cc | 557 ---------------- .../StationaryQubit/StationaryQubit_test.cc | 115 ---- 7 files changed, 128 insertions(+), 1878 deletions(-) create mode 100644 quisp/backends/ErrorTracking/Qubit_test.cc delete mode 100644 quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc delete mode 100644 quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc delete mode 100644 quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index 664ce4bee..1e1570523 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -264,6 +264,7 @@ void ErrorTrackingQubit::setFree() { // entangled_partner->entangled_partner = nullptr; entangled_partner = nullptr; } + updated_time = backend->getSimTime(); } void ErrorTrackingQubit::setRelaxedDensityMatrix() { density_matrix_collapsed << 0, 0, 0, 1; diff --git a/quisp/backends/ErrorTracking/Qubit_test.cc b/quisp/backends/ErrorTracking/Qubit_test.cc new file mode 100644 index 000000000..173868ead --- /dev/null +++ b/quisp/backends/ErrorTracking/Qubit_test.cc @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include "backends/ErrorTracking/types.h" +#include "test.h" + +namespace { +using namespace quisp_test::backends; +using Eigen::Matrix2cd; +using Eigen::Matrix4cd; +using Eigen::Vector4cd; +using quisp::backends::error_tracking::QuantumState; + +class EtQubitTest : public ::testing::Test { + protected: + virtual void SetUp() { + // to avoid the omnetpp::SimTime assertion + SimTime::setScaleExp(-9); + rng = new TestRNG(); + rng->double_value = .0; + backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); + qubit = dynamic_cast(backend->getQubit(0)); + partner_qubit = dynamic_cast(backend->getQubit(1)); + if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); + backend->setSimTime(SimTime(1, SIMTIME_US)); + fillParams(qubit); + } + + void fillParams(Qubit* qubit) { + // ceiled values should be: + // No error= 0.1, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 + double x_error_rate = .1; + double y_error_rate = .1; + double z_error_rate = .1; + double energy_excitation_rate = .1; + double energy_relaxation_rate = .1; + double completely_mixed_rate = 0; + qubit->setMemoryErrorRates(x_error_rate, y_error_rate, z_error_rate, energy_excitation_rate, energy_relaxation_rate, completely_mixed_rate); + } + + Qubit* qubit; + Qubit* partner_qubit; + std::unique_ptr backend; + TestRNG* rng; +}; + +TEST_F(EtQubitTest, getErrorMatrixTest) { + Matrix2cd err; + + err = qubit->getErrorMatrix(); + EXPECT_EQ(Matrix2cd::Identity(), err); + + Matrix2cd Z(2, 2); + Z << 1, 0, 0, -1; + qubit->addErrorZ(); + err = qubit->getErrorMatrix(); + EXPECT_EQ(Z, err); + qubit->setFree(); + + Matrix2cd X(2, 2); + X << 0, 1, 1, 0; + qubit->addErrorX(); + err = qubit->getErrorMatrix(); + EXPECT_EQ(X, err); + qubit->setFree(); + + Matrix2cd Y(2, 2); + Y << 0, Complex(0, -1), Complex(0, 1), 0; + qubit->addErrorX(); + qubit->addErrorZ(); + err = qubit->getErrorMatrix(); + EXPECT_EQ(Y, err); + qubit->setFree(); +} + +TEST_F(EtQubitTest, getQuantumState) { + qubit->setEntangledPartner(partner_qubit); + + QuantumState state; + + state = qubit->getQuantumState(); + Vector4cd state_vector(4); + state_vector << 1 / sqrt(2), 0, 0, 1 / sqrt(2); + Matrix4cd dm(4, 4); + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); + + qubit->addErrorX(); + state = qubit->getQuantumState(); + state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); + qubit->addErrorX(); + + partner_qubit->addErrorX(); + state = qubit->getQuantumState(); + state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); + partner_qubit->addErrorX(); + + qubit->addErrorZ(); + state = qubit->getQuantumState(); + state_vector << 1 / sqrt(2), 0, 0, -1 / sqrt(2); + dm = state_vector * state_vector.adjoint(); + EXPECT_EQ(dm, state.state_in_density_matrix); + EXPECT_EQ(state_vector, state.state_in_ket); +} + +TEST_F(EtQubitTest, setFreeUpdatesTime) { + qubit->setFree(); + EXPECT_EQ(qubit->updated_time, backend->getSimTime()); + auto last_updated_at = qubit->updated_time; + backend->setSimTime(10); + EXPECT_EQ(qubit->updated_time, last_updated_at); + qubit->setFree(); + EXPECT_EQ(qubit->updated_time, backend->getSimTime()); +} + +} // namespace diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index a41b950ef..5d2ac0462 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -80,6 +80,7 @@ class Backend : public ErrorTrackingBackend { using ErrorTrackingBackend::qubits; Backend(std::unique_ptr rng, std::unique_ptr config) : ErrorTrackingBackend(std::move(rng), std::move(config)) {} IQubit* getQubit(int id) { return this->getQubitInternal(new QubitId(id)); } + IQubit* getQubit(const IQubitId* id) override { throw std::runtime_error("do not call IQubit* getQubit(const IQubitId* id) in this test"); } IQubit* getQubitInternal(const IQubitId* id) { auto qubit = qubits.find(id); diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc deleted file mode 100644 index d4eedc302..000000000 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_gate_error_test.cc +++ /dev/null @@ -1,597 +0,0 @@ -#include -#include -#include -#include -#include "StationaryQubit.h" -#include "omnetpp/simtime.h" - -using namespace quisp::modules; -using namespace quisp::modules::common; -using namespace quisp_test; -namespace { - -// class Strategy : public TestComponentProviderStrategy { -// public: -// Strategy() : backend(new MockQuantumBackend()) {} -// ~Strategy() {} -// IQuantumBackend *getQuantumBackend() override { return backend; } -// MockQuantumBackend *backend; -// }; - -// class StatQubitTarget : public StationaryQubit { -// public: -// using StationaryQubit::applySingleQubitGateError; -// using StationaryQubit::applyTwoQubitGateError; -// using StationaryQubit::initialize; -// using StationaryQubit::par; -// using StationaryQubit::setSingleQubitGateErrorModel; -// using StationaryQubit::setTwoQubitGateErrorCeilings; -// StatQubitTarget() : StationaryQubit() { -// setComponentType(new TestModuleType("test qubit")); -// provider.setStrategy(std::make_unique()); -// } -// void reset() { -// setFree(true); -// updated_time = SimTime(0); -// no_density_matrix_nullptr_entangled_partner_ok = true; -// } -// void fillParams() { -// setParDouble(this, "emission_success_probability", 0.5); -// setParDouble(this, "memory_X_error_rate", 1.11111111e-7); -// setParDouble(this, "memory_Y_error_rate", 1.11111111e-7); -// setParDouble(this, "memory_Z_error_rate", 1.11111111e-7); -// setParDouble(this, "memory_energy_excitation_rate", 0.000198); -// setParDouble(this, "memory_energy_relaxation_rate", 0.00000198); -// setParDouble(this, "memory_completely_mixed_rate", 0); - -// // No error= 0.4, X error = 0.6, Z error = 0.8, Y error = 1.0 -// setParDouble(this, "Hgate_error_rate", 0.6); -// setParDouble(this, "Hgate_X_error_ratio", 1); -// setParDouble(this, "Hgate_Z_error_ratio", 1); -// setParDouble(this, "Hgate_Y_error_ratio", 1); - -// setParDouble(this, "Xgate_error_rate", 0.6); -// setParDouble(this, "Xgate_X_error_ratio", 1); -// setParDouble(this, "Xgate_Z_error_ratio", 1); -// setParDouble(this, "Xgate_Y_error_ratio", 1); - -// setParDouble(this, "Zgate_error_rate", 0.6); -// setParDouble(this, "Zgate_X_error_ratio", 1); -// setParDouble(this, "Zgate_Z_error_ratio", 1); -// setParDouble(this, "Zgate_Y_error_ratio", 1); - -// // clean = 0.1, -// // IX = 0.2, XI = 0.3, XX = 0.4, -// // IZ = 0.5, ZI = 0.6, ZZ = 0.7, -// // IY = 0.8, IY = 0.9, YY = 1.0 -// setParDouble(this, "CNOTgate_error_rate", 0.9); -// setParDouble(this, "CNOTgate_IX_error_ratio", 1); -// setParDouble(this, "CNOTgate_XI_error_ratio", 1); -// setParDouble(this, "CNOTgate_XX_error_ratio", 1); -// setParDouble(this, "CNOTgate_IZ_error_ratio", 1); -// setParDouble(this, "CNOTgate_ZI_error_ratio", 1); -// setParDouble(this, "CNOTgate_ZZ_error_ratio", 1); -// setParDouble(this, "CNOTgate_IY_error_ratio", 1); -// setParDouble(this, "CNOTgate_YI_error_ratio", 1); -// setParDouble(this, "CNOTgate_YY_error_ratio", 1); - -// setParDouble(this, "X_measurement_error_rate", 1.0 / 2000); -// setParDouble(this, "Y_measurement_error_rate", 1.0 / 2000); -// setParDouble(this, "Z_measurement_error_rate", 1.0 / 2000); - -// setParInt(this, "stationaryQubit_address", 1); -// setParInt(this, "node_address", 1); -// setParInt(this, "qnic_address", 1); -// setParInt(this, "qnic_type", 0); -// setParInt(this, "qnic_index", 0); -// setParDouble(this, "std", 0.5); - -// setParDouble(this, "photon_emitted_at", 0.0); -// setParDouble(this, "last_updated_at", 0.0); -// setParBool(this, "GOD_Xerror", false); -// setParBool(this, "GOD_Zerror", false); -// setParBool(this, "GOD_CMerror", false); -// setParBool(this, "GOD_EXerror", false); -// setParBool(this, "GOD_REerror", false); -// setParBool(this, "isBusy", false); -// setParInt(this, "GOD_entangled_stationaryQubit_address", 0); -// setParInt(this, "GOD_entangled_node_address", 0); -// setParInt(this, "GOD_entangled_qnic_address", 0); -// setParInt(this, "GOD_entangled_qnic_type", 0); -// setParDouble(this, "fidelity", -1.0); -// } -// }; - -// TEST(StatQubitGateErrorTest, SetSingleQubitGateErrorCeilings) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// setParDouble(qubit, "Xgate_error_rate", 0.1); -// setParDouble(qubit, "Xgate_X_error_ratio", 1); -// setParDouble(qubit, "Xgate_Z_error_ratio", 2); -// setParDouble(qubit, "Xgate_Y_error_ratio", 3); -// sim->registerComponent(qubit); -// qubit->setSingleQubitGateErrorModel(qubit->Xgate_error, std::string("Xgate")); -// auto &error_model = qubit->Xgate_error; -// EXPECT_FALSE(std::isnan(error_model.X_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.Y_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.Z_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.X_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.Z_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.Y_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.X_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.Y_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.Z_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.X_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.Z_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.Y_error_ceil)); -// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); -// EXPECT_DOUBLE_EQ(error_model.X_error_rate, 0.1 * 1 / 6); -// EXPECT_DOUBLE_EQ(error_model.Z_error_rate, 0.2 * 1 / 6); -// EXPECT_DOUBLE_EQ(error_model.Y_error_rate, 0.3 * 1 / 6); -// } - -// TEST(StatQubitGateErrorTest, SetSingleQubitGateErrorCeilings_div_by_zero) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// setParDouble(qubit, "Xgate_error_rate", 0.1); -// setParDouble(qubit, "Xgate_X_error_ratio", 0); -// setParDouble(qubit, "Xgate_Z_error_ratio", 0); -// setParDouble(qubit, "Xgate_Y_error_ratio", 0); -// sim->registerComponent(qubit); -// qubit->setSingleQubitGateErrorModel(qubit->Xgate_error, std::string("Xgate")); -// auto &error_model = qubit->Xgate_error; -// EXPECT_FALSE(std::isnan(error_model.X_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.Y_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.Z_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.X_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.Z_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.Y_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.X_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.Y_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.Z_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.X_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.Z_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.Y_error_ceil)); -// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); -// EXPECT_DOUBLE_EQ(error_model.X_error_rate, 0.1 * 1 / 3); -// EXPECT_DOUBLE_EQ(error_model.Z_error_rate, 0.1 * 1 / 3); -// EXPECT_DOUBLE_EQ(error_model.Y_error_rate, 0.1 * 1 / 3); -// } - -// TEST(StatQubitGateErrorTest, SetTwoQubitGateErrorCeilings) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// setParDouble(qubit, "CNOTgate_error_rate", 0.1); -// setParDouble(qubit, "CNOTgate_IX_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_XI_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_XX_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_IZ_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_ZI_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_ZZ_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_IY_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_YI_error_ratio", 1); -// setParDouble(qubit, "CNOTgate_YY_error_ratio", 1); -// sim->registerComponent(qubit); -// qubit->setTwoQubitGateErrorCeilings(qubit->CNOTgate_error, std::string("CNOTgate")); -// auto const &error_model = qubit->CNOTgate_error; -// EXPECT_FALSE(std::isnan(error_model.IX_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.XI_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.XX_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.IZ_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.ZI_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.ZZ_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.IY_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.YI_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.YY_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.XI_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.IX_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.XX_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.ZI_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.IZ_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.ZZ_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.YI_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.IY_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.YY_error_ceil)); - -// EXPECT_FALSE(std::isinf(error_model.XI_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.IX_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.XX_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.ZI_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.IZ_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.ZZ_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.YI_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.IY_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.YY_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.XI_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.IX_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.XX_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.ZI_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.IZ_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.ZZ_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.YI_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.IY_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.YY_error_ceil)); -// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); -// EXPECT_DOUBLE_EQ(error_model.XI_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.IX_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.XX_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.ZI_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.IZ_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.ZZ_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.YI_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.IY_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.YY_error_rate, 0.1 * 1 / 9); -// } - -// TEST(StatQubitGateErrorTest, SetTwoQubitGateErrorCeilings_div_by_zero) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// setParDouble(qubit, "CNOTgate_error_rate", 0.1); -// setParDouble(qubit, "CNOTgate_IX_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_XI_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_XX_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_IZ_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_ZI_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_ZZ_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_IY_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_YI_error_ratio", 0); -// setParDouble(qubit, "CNOTgate_YY_error_ratio", 0); -// sim->registerComponent(qubit); -// qubit->setTwoQubitGateErrorCeilings(qubit->CNOTgate_error, std::string("CNOTgate")); -// auto const &error_model = qubit->CNOTgate_error; -// EXPECT_FALSE(std::isnan(error_model.IX_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.XI_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.XX_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.IZ_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.ZI_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.ZZ_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.IY_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.YI_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.YY_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.XI_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.IX_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.XX_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.ZI_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.IZ_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.ZZ_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.YI_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.IY_error_ceil)); -// EXPECT_FALSE(std::isnan(error_model.YY_error_ceil)); - -// EXPECT_FALSE(std::isinf(error_model.XI_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.IX_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.XX_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.ZI_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.IZ_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.ZZ_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.YI_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.IY_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.YY_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.pauli_error_rate)); -// EXPECT_FALSE(std::isinf(error_model.No_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.XI_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.IX_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.XX_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.ZI_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.IZ_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.ZZ_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.YI_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.IY_error_ceil)); -// EXPECT_FALSE(std::isinf(error_model.YY_error_ceil)); -// EXPECT_DOUBLE_EQ(error_model.pauli_error_rate, 0.1); -// EXPECT_DOUBLE_EQ(error_model.XI_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.IX_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.XX_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.ZI_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.IZ_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.ZZ_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.YI_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.IY_error_rate, 0.1 * 1 / 9); -// EXPECT_DOUBLE_EQ(error_model.YY_error_rate, 0.1 * 1 / 9); -// } -// TEST(StatQubitGateErrorTest, do_nothing_single_qubit_gate) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// setParDouble(qubit, "Xgate_error_rate", 0.0); -// qubit->callInitialize(); -// qubit->reset(); -// qubit->par("GOD_Xerror") = true; -// qubit->par("GOD_Zerror") = true; -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(qubit->par("GOD_REerror")); -// EXPECT_FALSE(qubit->par("GOD_EXerror")); -// sim->registerComponent(qubit); - -// qubit->applySingleQubitGateError(qubit->Xgate_error); - -// EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(qubit->par("GOD_REerror")); -// EXPECT_FALSE(qubit->par("GOD_EXerror")); -// } - -// TEST(StatQubitGateErrorTest, do_nothing_two_qubit_gate) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// auto *qubit2 = new StatQubitTarget{}; -// qubit->fillParams(); -// qubit2->fillParams(); -// setParDouble(qubit, "CNOTgate_error_rate", 0.0); -// qubit->callInitialize(); -// qubit2->callInitialize(); -// qubit->reset(); -// qubit2->reset(); -// qubit->par("GOD_Xerror") = true; -// qubit->par("GOD_Zerror") = true; -// qubit2->par("GOD_Xerror") = true; -// qubit2->par("GOD_Zerror") = true; -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(qubit->par("GOD_REerror")); -// EXPECT_FALSE(qubit->par("GOD_EXerror")); -// EXPECT_TRUE(qubit2->par("GOD_Xerror")); -// EXPECT_TRUE(qubit2->par("GOD_Zerror")); -// EXPECT_FALSE(qubit2->par("GOD_REerror")); -// EXPECT_FALSE(qubit2->par("GOD_EXerror")); -// sim->registerComponent(qubit); -// sim->registerComponent(qubit2); - -// qubit->applyTwoQubitGateError(qubit->CNOTgate_error, qubit2); - -// EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(qubit->par("GOD_REerror")); -// EXPECT_FALSE(qubit->par("GOD_EXerror")); -// EXPECT_TRUE(qubit2->par("GOD_Xerror")); -// EXPECT_TRUE(qubit2->par("GOD_Zerror")); -// EXPECT_FALSE(qubit2->par("GOD_REerror")); -// EXPECT_FALSE(qubit2->par("GOD_EXerror")); -// } - -// TEST(StatQubitGateErrorTest, apply_single_qubit_gate_error) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); - -// qubit->callInitialize(); -// sim->registerComponent(qubit); -// sim->setSimTime(SimTime(1, SIMTIME_US)); -// // No error -// qubit->reset(); -// rng->doubleValue = 0.35; -// qubit->applySingleQubitGateError(qubit->Xgate_error); -// EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - -// // X error -// qubit->reset(); -// rng->doubleValue = 0.45; -// qubit->applySingleQubitGateError(qubit->Xgate_error); -// EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - -// // Z error -// qubit->reset(); -// rng->doubleValue = 0.65; -// qubit->applySingleQubitGateError(qubit->Xgate_error); -// EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - -// // Y error -// qubit->reset(); -// rng->doubleValue = 0.85; -// qubit->applySingleQubitGateError(qubit->Xgate_error); -// EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); -// } - -// TEST(StatQubitGateErrorTest, apply_two_qubit_gate_error) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit1 = new StatQubitTarget{}; -// auto *qubit2 = new StatQubitTarget{}; -// qubit1->fillParams(); -// qubit2->fillParams(); - -// qubit1->callInitialize(); -// qubit2->callInitialize(); -// sim->registerComponent(qubit1); -// sim->registerComponent(qubit2); -// sim->setSimTime(SimTime(1, SIMTIME_US)); - -// // No error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.05; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // IX error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.15; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // XI error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.25; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // XX error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.35; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // IZ error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.45; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // ZI error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.55; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // ZZ error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.65; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // IY error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.75; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // YI error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.85; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_FALSE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); - -// // YY error -// qubit1->reset(); -// qubit2->reset(); -// rng->doubleValue = 0.95; -// qubit1->applyTwoQubitGateError(qubit1->CNOTgate_error, qubit2); -// EXPECT_TRUE(qubit1->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit1->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit1->par("GOD_CMerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Xerror").boolValue()); -// EXPECT_TRUE(qubit2->par("GOD_Zerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_EXerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_REerror").boolValue()); -// EXPECT_FALSE(qubit2->par("GOD_CMerror").boolValue()); -// } -} // namespace diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc deleted file mode 100644 index 220554942..000000000 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_measurement_test.cc +++ /dev/null @@ -1,609 +0,0 @@ -#include -#include -#include -#include -#include "StationaryQubit.h" -#include "modules/QNIC/StationaryQubit/IStationaryQubit.h" -#include "omnetpp/simtime.h" - -using namespace quisp::modules; -using namespace quisp::modules::common; -using namespace quisp_test; -namespace { - -class Strategy : public TestComponentProviderStrategy { - public: - Strategy() : backend(new MockQuantumBackend()) {} - ~Strategy() {} - IQuantumBackend *getQuantumBackend() override { return backend; } - MockQuantumBackend *backend; -}; - -class StatQubitTarget : public StationaryQubit { - public: - using StationaryQubit::addXerror; - using StationaryQubit::addZerror; - using StationaryQubit::correlationMeasureX; - using StationaryQubit::correlationMeasureY; - using StationaryQubit::correlationMeasureZ; - using StationaryQubit::initialize; - using StationaryQubit::localMeasureX; - using StationaryQubit::localMeasureY; - using StationaryQubit::localMeasureZ; - using StationaryQubit::par; - StatQubitTarget() : StationaryQubit() { - setComponentType(new TestModuleType("test qubit")); - provider.setStrategy(std::make_unique()); - } - void reset() { - this->god_err.has_x_error = false; - this->god_err.has_z_error = false; - // this->god_err.has_Y_error = false; not implemeted yet - } - void fillParams() { - setParDouble(this, "emission_success_probability", 0.5); - setParDouble(this, "memory_x_error_rate", 1.11111111e-7); - setParDouble(this, "memory_y_error_rate", 1.11111111e-7); - setParDouble(this, "memory_z_error_rate", 1.11111111e-7); - setParDouble(this, "memory_energy_excitation_rate", 0.000198); - setParDouble(this, "memory_energy_relaxation_rate", 0.00000198); - setParDouble(this, "memory_completely_mixed_rate", 0); - - // No error= 0.4, X error = 0.6, Z error = 0.8, Y error = 1.0 - setParDouble(this, "h_gate_error_rate", 0.6); - setParDouble(this, "h_gate_x_error_ratio", 1); - setParDouble(this, "h_gate_z_error_ratio", 1); - setParDouble(this, "h_gate_y_error_ratio", 1); - - setParDouble(this, "x_gate_error_rate", 0.6); - setParDouble(this, "x_gate_x_error_ratio", 1); - setParDouble(this, "x_gate_z_error_ratio", 1); - setParDouble(this, "x_gate_y_error_ratio", 1); - - setParDouble(this, "z_gate_error_rate", 0.6); - setParDouble(this, "z_gate_x_error_ratio", 1); - setParDouble(this, "z_gate_z_error_ratio", 1); - setParDouble(this, "z_gate_y_error_ratio", 1); - - // clean = 0.1, - // IX = 0.2, XI = 0.3, XX = 0.4, - // IZ = 0.5, ZI = 0.6, ZZ = 0.7, - // IY = 0.8, IY = 0.9, YY = 1.0 - setParDouble(this, "cnot_gate_error_rate", 0.9); - setParDouble(this, "cnot_gate_ix_error_ratio", 1); - setParDouble(this, "cnot_gate_xi_error_ratio", 1); - setParDouble(this, "cnot_gate_xx_error_ratio", 1); - setParDouble(this, "cnot_gate_iz_error_ratio", 1); - setParDouble(this, "cnot_gate_zi_error_ratio", 1); - setParDouble(this, "cnot_gate_zz_error_ratio", 1); - setParDouble(this, "cnot_gate_iy_error_ratio", 1); - setParDouble(this, "cnot_gate_yi_error_ratio", 1); - setParDouble(this, "cnot_gate_yy_error_ratio", 1); - - setParDouble(this, "x_measurement_error_rate", 1.0 / 2000); - setParDouble(this, "y_measurement_error_rate", 1.0 / 2000); - setParDouble(this, "z_measurement_error_rate", 1.0 / 2000); - - setParInt(this, "stationary_qubit_address", 1); - setParInt(this, "node_address", 1); - setParInt(this, "qnic_address", 1); - setParInt(this, "qnic_type", 0); - setParInt(this, "qnic_index", 0); - setParDouble(this, "emission_jittering_standard_deviation", 0.5); - } -}; - -// TEST(StatQubitMeasurementTest, SetMeasurementErrorRate) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// setParDouble(qubit, "X_measurement_error_rate", 0.1); -// setParDouble(qubit, "Y_measurement_error_rate", 0.2); -// setParDouble(qubit, "Z_measurement_error_rate", 0.4); -// sim->registerComponent(qubit); -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// auto &error_model = qubit->Measurement_error; -// EXPECT_FALSE(std::isnan(error_model.x_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.y_error_rate)); -// EXPECT_FALSE(std::isnan(error_model.z_error_rate)); -// EXPECT_DOUBLE_EQ(error_model.x_error_rate, 0.1); -// EXPECT_DOUBLE_EQ(error_model.y_error_rate, 0.2); -// EXPECT_DOUBLE_EQ(error_model.z_error_rate, 0.4); -// } - -// TEST(StatQubitMeasurementTest, CorrelationMeasureXwithoutError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); -// } - -// TEST(StatQubitMeasurementTest, CorrelationMeasureXwithError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); - -// // X error -// qubit->addXerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); - -// // Y error -// qubit->addZerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); - -// // Z error -// qubit->addXerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::HAS_Z_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureX(), quisp::types::MeasureXResult::NO_Z_ERROR); -// } - -// TEST(StatQubitMeasurementTest, CorrelationMeasureYwithoutError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); -// } - -// TEST(StatQubitMeasurementTest, CorrelationMeasureYwithError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); - -// // X error -// qubit->addXerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); - -// // Y error -// qubit->addZerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); - -// // Z error -// qubit->addXerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::HAS_XZ_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureY(), quisp::types::MeasureYResult::NO_XZ_ERROR); -// } - -// TEST(StatQubitMeasurementTest, CorrelationMeasureZwithoutError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); -// } - -// TEST(StatQubitMeasurementTest, CorrelationMeasureZwithError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); - -// // X error -// qubit->addXerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); - -// // Y error -// qubit->addZerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); - -// // Z error -// qubit->addXerror(); -// rng->doubleValue = 0.5; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::NO_X_ERROR); -// rng->doubleValue = 1.0 / 3000; -// EXPECT_EQ(qubit->correlationMeasureZ(), quisp::types::MeasureZResult::HAS_X_ERROR); -// } - -// TEST(StatQubitMeasurementTest, localXMeasurementWithoutError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// auto *another_qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// another_qubit->fillParams(); -// qubit->entangled_partner = another_qubit; -// another_qubit->entangled_partner = qubit; -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); - -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); -// } - -// TEST(StatQubitMeasurementTest, localXMeasurementWithError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// auto *another_qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// another_qubit->fillParams(); -// setParDouble(qubit, "X_measurement_error_rate", 0.99); -// qubit->entangled_partner = another_qubit; -// another_qubit->entangled_partner = qubit; -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); - -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureX(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); -// } - -// TEST(StatQubitMeasurementTest, localZMeasurementWithoutError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// auto *another_qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// another_qubit->fillParams(); -// qubit->entangled_partner = another_qubit; -// another_qubit->entangled_partner = qubit; -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); - -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); -// } - -// TEST(StatQubitMeasurementTest, localZMeasurementWithError) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// auto *another_qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// another_qubit->fillParams(); -// setParDouble(qubit, "Z_measurement_error_rate", 0.99); -// qubit->entangled_partner = another_qubit; -// another_qubit->entangled_partner = qubit; -// qubit->setMeasurementErrorModel(qubit->Measurement_error); -// sim->registerComponent(qubit); - -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.7; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::MINUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_TRUE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); - -// qubit->reset(); -// another_qubit->reset(); -// qubit->addZerror(); -// qubit->addXerror(); -// rng->doubleValue = 0.3; -// EXPECT_EQ(qubit->localMeasureZ(), quisp::types::EigenvalueResult::PLUS_ONE); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Xerror")); -// EXPECT_FALSE(another_qubit->par("GOD_Zerror")); -// } - -} // end namespace diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc deleted file mode 100644 index 026fbfd09..000000000 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_memory_error_test.cc +++ /dev/null @@ -1,557 +0,0 @@ -#include -#include -#include -#include -#include "StationaryQubit.h" -#include "omnetpp/simtime.h" - -using namespace quisp::modules; -using namespace quisp::modules::common; -using namespace quisp_test; -namespace { -// class Strategy : public TestComponentProviderStrategy { -// public: -// Strategy() : backend(new MockQuantumBackend()) {} -// ~Strategy() {} -// IQuantumBackend *getQuantumBackend() override { return backend; } -// MockQuantumBackend *backend; -// }; - -class StatQubitTarget : public StationaryQubit { - public: - using StationaryQubit::applyMemoryError; - using StationaryQubit::initialize; - using StationaryQubit::par; - StatQubitTarget() : StationaryQubit() { - setComponentType(new TestModuleType("test qubit")); - provider.setStrategy(std::make_unique()); - } - void reset() { - setFree(true); - updated_time = SimTime(0); - no_density_matrix_nullptr_entangled_partner_ok = true; - } - void fillParams() { - // see networks/omnetpp.ini - setParDouble(this, "emission_success_probability", 0.5); - setParDouble(this, "memory_X_error_rate", 1.11111111e-7); - setParDouble(this, "memory_Y_error_rate", 1.11111111e-7); - setParDouble(this, "memory_Z_error_rate", 1.11111111e-7); - setParDouble(this, "memory_energy_excitation_rate", 0.000198); - setParDouble(this, "memory_energy_relaxation_rate", 0.00000198); - setParDouble(this, "memory_completely_mixed_rate", 0); - - setParDouble(this, "Hgate_error_rate", 1. / 2000); - setParDouble(this, "Hgate_X_error_ratio", 0); - setParDouble(this, "Hgate_Z_error_ratio", 0); - setParDouble(this, "Hgate_Y_error_ratio", 0); - - setParDouble(this, "Xgate_error_rate", 1. / 2000); - setParDouble(this, "Xgate_X_error_ratio", 0); - setParDouble(this, "Xgate_Z_error_ratio", 0); - setParDouble(this, "Xgate_Y_error_ratio", 0); - - setParDouble(this, "Zgate_error_rate", 1. / 2000); - setParDouble(this, "Zgate_X_error_ratio", 0); - setParDouble(this, "Zgate_Z_error_ratio", 0); - setParDouble(this, "Zgate_Y_error_ratio", 0); - - setParDouble(this, "CNOTgate_error_rate", 1. / 2000); - setParDouble(this, "CNOTgate_IX_error_ratio", 1); - setParDouble(this, "CNOTgate_XI_error_ratio", 1); - setParDouble(this, "CNOTgate_XX_error_ratio", 1); - setParDouble(this, "CNOTgate_IZ_error_ratio", 1); - setParDouble(this, "CNOTgate_ZI_error_ratio", 1); - setParDouble(this, "CNOTgate_ZZ_error_ratio", 1); - setParDouble(this, "CNOTgate_IY_error_ratio", 1); - setParDouble(this, "CNOTgate_YI_error_ratio", 1); - setParDouble(this, "CNOTgate_YY_error_ratio", 1); - - setParDouble(this, "X_measurement_error_rate", 1. / 2000); - setParDouble(this, "Y_measurement_error_rate", 1. / 2000); - setParDouble(this, "Z_measurement_error_rate", 1. / 2000); - - setParInt(this, "stationaryQubit_address", 1); - setParInt(this, "node_address", 1); - setParInt(this, "qnic_address", 1); - setParInt(this, "qnic_type", 0); - setParInt(this, "qnic_index", 0); - setParDouble(this, "std", 0.5); - - setParDouble(this, "photon_emitted_at", 0.0); - setParDouble(this, "last_updated_at", 0.0); - setParBool(this, "GOD_Xerror", false); - setParBool(this, "GOD_Zerror", false); - setParBool(this, "GOD_CMerror", false); - setParBool(this, "GOD_EXerror", false); - setParBool(this, "GOD_REerror", false); - setParBool(this, "isBusy", false); - setParInt(this, "GOD_entangled_stationaryQubit_address", 0); - setParInt(this, "GOD_entangled_node_address", 0); - setParInt(this, "GOD_entangled_qnic_address", 0); - setParInt(this, "GOD_entangled_qnic_type", 0); - setParDouble(this, "fidelity", -1.0); - } -}; - -TEST(StatQubitMemoryErrorTest, do_nothing) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->callInitialize(); - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->par("GOD_Zerror") = true; - EXPECT_TRUE(qubit->par("GOD_Xerror")); - EXPECT_TRUE(qubit->par("GOD_Zerror")); - EXPECT_FALSE(qubit->par("GOD_REerror")); - EXPECT_FALSE(qubit->par("GOD_EXerror")); - sim->registerComponent(qubit); - -// // if current time and updated_time are same, do nothing -// EXPECT_EQ(qubit->updated_time, SimTime(0)); -// sim->setSimTime(SimTime(0, SIMTIME_US)); -// qubit->applyMemoryError(); - - EXPECT_EQ(qubit->updated_time, SimTime(0, SIMTIME_US)); - EXPECT_TRUE(qubit->par("GOD_Xerror")); - EXPECT_TRUE(qubit->par("GOD_Zerror")); - EXPECT_FALSE(qubit->par("GOD_REerror")); - EXPECT_FALSE(qubit->par("GOD_EXerror")); -} -TEST(StatQubitMemoryErrorTest, update_timestamp) { - auto *sim = prepareSimulation(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - qubit->callInitialize(); - qubit->reset(); - EXPECT_EQ(qubit->updated_time, SimTime(0)); - sim->registerComponent(qubit); - sim->setSimTime(SimTime(1, SIMTIME_US)); - qubit->applyMemoryError(); - EXPECT_EQ(qubit->updated_time, SimTime(1, SIMTIME_US)); -} -TEST(StatQubitMemoryErrorTest, apply_memory_error_no_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - - // Initial_condition << 1, 0, 0, 0, 0, 0, 0; - // this means take 1st row of MemoryTransitionMatrix - // ceiled values should be: - // No error= 0.5, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_X_error_rate", .1); - setParDouble(qubit, "memory_Y_error_rate", .1); - setParDouble(qubit, "memory_Z_error_rate", .1); - setParDouble(qubit, "memory_energy_excitation_rate", .1); - setParDouble(qubit, "memory_energy_relaxation_rate", .1); - setParDouble(qubit, "memory_completely_mixed_rate", 0); - qubit->callInitialize(); - sim->registerComponent(qubit); - sim->setSimTime(SimTime(1, SIMTIME_US)); - - // X error - qubit->reset(); - rng->doubleValue = 0.55; - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Z error - rng->doubleValue = 0.65; - qubit->reset(); - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Y error - rng->doubleValue = 0.75; - qubit->reset(); - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Excitation error - rng->doubleValue = 0.85; - qubit->reset(); - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Relaxation error - rng->doubleValue = 0.95; - qubit->reset(); - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); -} - -TEST(StatQubitMemoryErrorTest, apply_memory_error_X_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - - // Initial_condition << 0, 1, 0, 0, 0, 0, 0; - // this means take 2nd row of MemoryTransitionMatrix - // ceiled values should be: - // No error= 0.1, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_X_error_rate", .1); - setParDouble(qubit, "memory_Y_error_rate", .1); - setParDouble(qubit, "memory_Z_error_rate", .1); - setParDouble(qubit, "memory_energy_excitation_rate", .1); - setParDouble(qubit, "memory_energy_relaxation_rate", .1); - setParDouble(qubit, "memory_completely_mixed_rate", 0); - qubit->callInitialize(); - sim->registerComponent(qubit); - sim->setSimTime(SimTime(1, SIMTIME_US)); - - // X error - qubit->reset(); - qubit->par("GOD_Xerror") = true; - rng->doubleValue = 0.55; - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Z error - rng->doubleValue = 0.65; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Y error - rng->doubleValue = 0.75; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Excitation error - rng->doubleValue = 0.85; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Relaxation error - rng->doubleValue = 0.95; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); -} - -TEST(StatQubitMemoryErrorTest, apply_memory_error_Z_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - - // Initial_condition << 0, 0, 1, 0, 0, 0, 0; - // this means take 3rd row of MemoryTransitionMatrix - // ceiled values should be: - // No error= 0.1, X error = 0.6, Z error = 0.7, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_X_error_rate", .1); - setParDouble(qubit, "memory_Y_error_rate", .1); - setParDouble(qubit, "memory_Z_error_rate", .1); - setParDouble(qubit, "memory_energy_excitation_rate", .1); - setParDouble(qubit, "memory_energy_relaxation_rate", .1); - setParDouble(qubit, "memory_completely_mixed_rate", 0); - qubit->callInitialize(); - sim->registerComponent(qubit); - sim->setSimTime(SimTime(1, SIMTIME_US)); - - // X error - qubit->reset(); - qubit->par("GOD_Xerror") = true; - rng->doubleValue = 0.55; - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Z error - rng->doubleValue = 0.65; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Y error - rng->doubleValue = 0.75; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Excitation error - rng->doubleValue = 0.85; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Relaxation error - rng->doubleValue = 0.95; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); -} - -TEST(StatQubitMemoryErrorTest, apply_memory_error_Y_error) { - auto *sim = prepareSimulation(); - auto *rng = useTestRNG(); - auto *qubit = new StatQubitTarget{}; - qubit->fillParams(); - - // Initial_condition << 0, 0, 0, 1, 0, 0, 0; - // this means take 4th row of MemoryTransitionMatrix - // ceiled values should be: - // No error= 0.1, X error = 0.2, Z error = 0.3, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_X_error_rate", .1); - setParDouble(qubit, "memory_Y_error_rate", .1); - setParDouble(qubit, "memory_Z_error_rate", .1); - setParDouble(qubit, "memory_energy_excitation_rate", .1); - setParDouble(qubit, "memory_energy_relaxation_rate", .1); - setParDouble(qubit, "memory_completely_mixed_rate", 0); - qubit->callInitialize(); - sim->registerComponent(qubit); - sim->setSimTime(SimTime(1, SIMTIME_US)); - - // X error - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->par("GOD_Zerror") = true; - rng->doubleValue = 0.15; - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Z error - rng->doubleValue = 0.25; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->par("GOD_Zerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Y error - rng->doubleValue = 0.5; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->par("GOD_Zerror") = true; - qubit->applyMemoryError(); - EXPECT_TRUE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Excitation error - rng->doubleValue = 0.85; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->par("GOD_Zerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Relaxation error - rng->doubleValue = 0.95; - qubit->reset(); - qubit->par("GOD_Xerror") = true; - qubit->par("GOD_Zerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); -} - -// TEST(StatQubitMemoryErrorTest, apply_memory_error_excitation_error) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); - - // Initial_condition << 0, 0, 0, 0, 1, 0, 0; - // this means take 5th row of MemoryTransitionMatrix - // ceiled values should be: - // No error= 0.1, X error = 0.2, Z error = 0.3, Y error = 0.8, Excitation = 0.9, Relaxation = 1.0 - setParDouble(qubit, "memory_X_error_rate", .1); - setParDouble(qubit, "memory_Y_error_rate", .1); - setParDouble(qubit, "memory_Z_error_rate", .1); - setParDouble(qubit, "memory_energy_excitation_rate", .1); - setParDouble(qubit, "memory_energy_relaxation_rate", .1); - setParDouble(qubit, "memory_completely_mixed_rate", 0); - qubit->callInitialize(); - sim->registerComponent(qubit); - sim->setSimTime(SimTime(1, SIMTIME_US)); - - // X error - qubit->reset(); - qubit->par("GOD_EXerror") = true; - rng->doubleValue = 0.15; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Z error - rng->doubleValue = 0.25; - qubit->reset(); - qubit->par("GOD_EXerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Y error - rng->doubleValue = 0.5; - qubit->reset(); - qubit->par("GOD_EXerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Excitation error - rng->doubleValue = 0.85; - qubit->reset(); - qubit->par("GOD_EXerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Relaxation error - rng->doubleValue = 0.95; - qubit->reset(); - qubit->par("GOD_EXerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); -} - -// TEST(StatQubitMemoryErrorTest, apply_memory_error_relaxation_error) { -// auto *sim = prepareSimulation(); -// auto *rng = useTestRNG(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); - - // Initial_condition << 0, 0, 0, 0, 0, 1, 0; - // this means take 6th row of MemoryTransitionMatrix - // ceiled values should be: - // No error= 0, X error = 0, Z error = 0, Y error = 0, Excitation = 0.1, Relaxation = 1.0 - setParDouble(qubit, "memory_X_error_rate", .1); - setParDouble(qubit, "memory_Y_error_rate", .1); - setParDouble(qubit, "memory_Z_error_rate", .1); - setParDouble(qubit, "memory_energy_excitation_rate", .1); - setParDouble(qubit, "memory_energy_relaxation_rate", .1); - setParDouble(qubit, "memory_completely_mixed_rate", 0); - qubit->callInitialize(); - sim->registerComponent(qubit); - sim->setSimTime(SimTime(1, SIMTIME_US)); - - // Excitation error - rng->doubleValue = 0.05; - qubit->reset(); - qubit->par("GOD_REerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); - - // Relaxation error - rng->doubleValue = 0.95; - qubit->reset(); - qubit->par("GOD_REerror") = true; - qubit->applyMemoryError(); - EXPECT_FALSE(qubit->par("GOD_Xerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_Zerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_EXerror").boolValue()); - EXPECT_TRUE(qubit->par("GOD_REerror").boolValue()); - EXPECT_FALSE(qubit->par("GOD_CMerror").boolValue()); -} - -} // namespace diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 3cc1c7d43..c4599fe3a 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -159,41 +159,6 @@ TEST_F(StatQubitTest, init) { delete backend_qubit; } -// TEST(StatQubitTest, setFree) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// sim->registerComponent(qubit); -// qubit->fillParams(); -// qubit->callInitialize(); - -// qubit->setFree(true); -// EXPECT_EQ(qubit->updated_time, simTime()); -// auto last_updated_at = qubit->updated_time; -// sim->setSimTime(10); -// EXPECT_EQ(qubit->updated_time, last_updated_at); -// qubit->setFree(true); -// EXPECT_EQ(qubit->updated_time, simTime()); - -// } - -// TEST(StatQubitTest, setFreeUpdatesTime) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// sim->registerComponent(qubit); -// qubit->fillParams(); -// qubit->callInitialize(); - -// qubit->setFree(true); -// EXPECT_EQ(qubit->updated_time, simTime()); - -// auto last_updated_at = qubit->updated_time; -// sim->setSimTime(10); -// EXPECT_EQ(qubit->updated_time, last_updated_at); - -// qubit->setFree(true); -// EXPECT_EQ(qubit->updated_time, simTime()); -// } - // TEST(StatQubitTest, addXError) { // auto *sim = prepareSimulation(); // auto *qubit = new StatQubitTarget{}; @@ -218,84 +183,4 @@ TEST_F(StatQubitTest, init) { // EXPECT_FALSE(qubit->par("GOD_Zerror")); // } -// TEST(StatQubitTest, getErrorMatrixTest) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// sim->registerComponent(qubit); -// qubit->callInitialize(); -// Matrix2cd err; - -// err = qubit->getErrorMatrix(qubit); -// EXPECT_EQ(Matrix2cd::Identity(), err); - -// Matrix2cd Z(2, 2); -// Z << 1, 0, 0, -1; -// qubit->addZerror(); -// err = qubit->getErrorMatrix(qubit); -// EXPECT_EQ(Z, err); -// qubit->setFree(true); - -// Matrix2cd X(2, 2); -// X << 0, 1, 1, 0; -// qubit->addXerror(); -// err = qubit->getErrorMatrix(qubit); -// EXPECT_EQ(X, err); -// qubit->setFree(true); - -// Matrix2cd Y(2, 2); -// Y << 0, Complex(0, -1), Complex(0, 1), 0; -// qubit->addXerror(); -// qubit->addZerror(); -// err = qubit->getErrorMatrix(qubit); -// EXPECT_EQ(Y, err); -// qubit->setFree(true); -// } - -// TEST(StatQubitTest, getQuantumState) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// auto *partner_qubit = new StatQubitTarget{}; -// sim->registerComponent(qubit); -// sim->registerComponent(partner_qubit); -// qubit->fillParams(); -// qubit->callInitialize(); -// partner_qubit->fillParams(); -// partner_qubit->callInitialize(); -// qubit->setEntangledPartnerInfo(partner_qubit); - -// quantum_state state; - -// state = qubit->getQuantumState(); -// Vector4cd state_vector(4); -// state_vector << 1 / sqrt(2), 0, 0, 1 / sqrt(2); -// Matrix4cd dm(4, 4); -// dm = state_vector * state_vector.adjoint(); -// EXPECT_EQ(dm, state.state_in_density_matrix); -// EXPECT_EQ(state_vector, state.state_in_ket); - -// qubit->addXerror(); -// state = qubit->getQuantumState(); -// state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; -// dm = state_vector * state_vector.adjoint(); -// EXPECT_EQ(dm, state.state_in_density_matrix); -// EXPECT_EQ(state_vector, state.state_in_ket); -// qubit->addXerror(); - -// partner_qubit->addXerror(); -// state = qubit->getQuantumState(); -// state_vector << 0, 1 / sqrt(2), 1 / sqrt(2), 0; -// dm = state_vector * state_vector.adjoint(); -// EXPECT_EQ(dm, state.state_in_density_matrix); -// EXPECT_EQ(state_vector, state.state_in_ket); -// partner_qubit->addXerror(); - -// qubit->addZerror(); -// state = qubit->getQuantumState(); -// state_vector << 1 / sqrt(2), 0, 0, -1 / sqrt(2); -// dm = state_vector * state_vector.adjoint(); -// EXPECT_EQ(dm, state.state_in_density_matrix); -// EXPECT_EQ(state_vector, state.state_in_ket); -// qubit->addZerror(); -// } } // namespace From 5b34b32566a093081e2a091342e4f6522f27ca42 Mon Sep 17 00:00:00 2001 From: zigen Date: Sat, 16 Apr 2022 20:20:19 +0900 Subject: [PATCH 18/43] update EtBackend simTime to sync before getSimTime --- quisp/backends/ErrorTracking/Backend.cc | 9 ++++++++- quisp/backends/ErrorTracking/Backend.h | 7 +++++++ quisp/backends/ErrorTracking/Qubit.cc | 3 --- quisp/backends/ErrorTracking/Qubit.h | 1 - quisp/modules/Backend/Backend.cc | 5 +++-- quisp/modules/Backend/Backend.h | 6 ++++-- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/quisp/backends/ErrorTracking/Backend.cc b/quisp/backends/ErrorTracking/Backend.cc index e3b461540..476bc29d9 100644 --- a/quisp/backends/ErrorTracking/Backend.cc +++ b/quisp/backends/ErrorTracking/Backend.cc @@ -13,6 +13,10 @@ ErrorTrackingBackend::ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration, ICallback* cb) + : ErrorTrackingBackend(std::move(rng), std::move(configuration)) { + callback = cb; +} ErrorTrackingBackend::~ErrorTrackingBackend() { for (auto& pair : qubits) { @@ -47,7 +51,10 @@ std::unique_ptr ErrorTrackingBackend::getDefaultConfiguration() // copy the default backend configuration for each qubit return std::make_unique(*config.get()); } -const SimTime& ErrorTrackingBackend::getSimTime() { return current_time; } +const SimTime& ErrorTrackingBackend::getSimTime() { + if (callback != nullptr) callback->willUpdate(*this); + return current_time; +} void ErrorTrackingBackend::setSimTime(SimTime time) { current_time = time; } double ErrorTrackingBackend::dblrand() { return rng->doubleRandom(); } diff --git a/quisp/backends/ErrorTracking/Backend.h b/quisp/backends/ErrorTracking/Backend.h index 3680f3cb5..996e34bd9 100644 --- a/quisp/backends/ErrorTracking/Backend.h +++ b/quisp/backends/ErrorTracking/Backend.h @@ -21,7 +21,13 @@ using omnetpp::SimTime; class ErrorTrackingBackend : public IQuantumBackend { public: + class ICallback { + public: + virtual ~ICallback() {} + virtual void willUpdate(ErrorTrackingBackend& backend) = 0; + }; ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration); + ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration, ICallback* callback); ~ErrorTrackingBackend(); IQubit* getQubit(const IQubitId* id) override; IQubit* getQubit(const IQubitId* id, std::unique_ptr configuration) override; @@ -35,6 +41,7 @@ class ErrorTrackingBackend : public IQuantumBackend { SimTime current_time; const std::unique_ptr rng; std::unique_ptr config; + ICallback* callback = nullptr; }; } // namespace quisp::backends::error_tracking diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index 1e1570523..cf2f2a3a2 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -122,7 +122,6 @@ void ErrorTrackingQubit::applyTwoQubitGateError(TwoQubitGateErrorModel const& er } } void ErrorTrackingQubit::applyMemoryError() { - // update(); if (entangled_partner == nullptr && density_matrix_collapsed(0, 0).real() == -111 && !no_density_matrix_nullptr_entangled_partner_ok) { throw std::runtime_error("This must not happen in apply memory error"); } @@ -310,8 +309,6 @@ void ErrorTrackingQubit::setCompletelyMixedDensityMatrix() { } } -void ErrorTrackingQubit::update() { updated_time = backend->getSimTime(); } - MeasureXResult ErrorTrackingQubit::correlationMeasureX() { bool error = has_z_error; if (backend->dblrand() < measurement_err.x_error_rate) { diff --git a/quisp/backends/ErrorTracking/Qubit.h b/quisp/backends/ErrorTracking/Qubit.h index c60afdad1..e763502ee 100644 --- a/quisp/backends/ErrorTracking/Qubit.h +++ b/quisp/backends/ErrorTracking/Qubit.h @@ -70,7 +70,6 @@ class ErrorTrackingQubit : public IQubit { Matrix2cd getErrorMatrix(); QuantumState getQuantumState(); MeasurementOperator randomMeasurementBasisSelection(); - void update(); // constants SingleGateErrorModel gate_err_h; diff --git a/quisp/modules/Backend/Backend.cc b/quisp/modules/Backend/Backend.cc index a776184c4..67958775e 100644 --- a/quisp/modules/Backend/Backend.cc +++ b/quisp/modules/Backend/Backend.cc @@ -1,4 +1,5 @@ #include "Backend.h" +#include "backends/ErrorTracking/Qubit.h" namespace quisp::modules::backend { @@ -54,9 +55,9 @@ void BackendContainer::configureErrorTrackingBackend() { conf->memory_relaxation_rate = par("memory_energy_relaxation_rate").doubleValue(); conf->memory_completely_mixed_rate = par("memory_completely_mixed_rate").doubleValue(); - backend = std::make_unique(std::make_unique(this), std::move(conf)); + backend = std::make_unique(std::make_unique(this), std::move(conf), static_cast(this)); } - +void BackendContainer::willUpdate(ErrorTrackingBackend& backend) { backend.setSimTime(omnetpp::simTime()); } void BackendContainer::finish() {} IQuantumBackend* BackendContainer::getQuantumBackend() { diff --git a/quisp/modules/Backend/Backend.h b/quisp/modules/Backend/Backend.h index ba66f9b0a..91a7c6dc2 100644 --- a/quisp/modules/Backend/Backend.h +++ b/quisp/modules/Backend/Backend.h @@ -3,6 +3,7 @@ #include #include #include "RNG.h" +#include "backends/ErrorTracking/Qubit.h" namespace quisp::modules::backend { using quisp::modules::common::ErrorTrackingBackend; @@ -10,7 +11,7 @@ using quisp::modules::common::ErrorTrackingConfiguration; using quisp::modules::common::IQuantumBackend; using rng::RNG; -class BackendContainer : public omnetpp::cSimpleModule { +class BackendContainer : public omnetpp::cSimpleModule, ErrorTrackingBackend::ICallback { public: BackendContainer(); ~BackendContainer(); @@ -19,10 +20,11 @@ class BackendContainer : public omnetpp::cSimpleModule { void finish() override; IQuantumBackend* getQuantumBackend(); + void willUpdate(ErrorTrackingBackend& backend) override; protected: void configureErrorTrackingBackend(); - std::unique_ptr backend; + std::unique_ptr backend = nullptr; }; Define_Module(BackendContainer); From 02469ddca2efa1ea6f046cf580af071e145a0889 Mon Sep 17 00:00:00 2001 From: zigen Date: Sat, 16 Apr 2022 20:53:12 +0900 Subject: [PATCH 19/43] add more EtQubit tests --- quisp/backends/ErrorTracking/Qubit_test.cc | 52 ++++++++++++++ quisp/backends/ErrorTracking/test.h | 1 + .../StationaryQubit/StationaryQubit_test.cc | 70 ------------------- 3 files changed, 53 insertions(+), 70 deletions(-) diff --git a/quisp/backends/ErrorTracking/Qubit_test.cc b/quisp/backends/ErrorTracking/Qubit_test.cc index 173868ead..34914b5dd 100644 --- a/quisp/backends/ErrorTracking/Qubit_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_test.cc @@ -123,4 +123,56 @@ TEST_F(EtQubitTest, setFreeUpdatesTime) { EXPECT_EQ(qubit->updated_time, backend->getSimTime()); } +TEST_F(EtQubitTest, initialize_memory_transition_matrix) { + qubit->setMemoryErrorRates(.011, .012, .013, .014, .015, .0); + + auto mat = qubit->memory_transition_matrix; + + // each element means: "Clean Xerror Zerror Yerror Excited Relaxed Mixed" + Eigen::RowVectorXd row0(7); + double sigma = .011 + .013 + .012 + .014 + .015; + row0 << 1 - sigma, .011, .013, .012, .014, .015, .0; + ASSERT_EQ(mat.row(0), row0); + + Eigen::RowVectorXd row1(7); + row1 << .011, 1 - sigma, .012, .013, .014, .015, .0; + ASSERT_EQ(mat.row(1), row1); + + Eigen::RowVectorXd row2(7); + row2 << .013, .012, 1 - sigma, .011, .014, .015, .0; + ASSERT_EQ(mat.row(2), row2); + + Eigen::RowVectorXd row3(7); + row3 << .012, .013, .011, 1 - sigma, .014, .015, .0; + ASSERT_EQ(mat.row(3), row3); + + Eigen::RowVectorXd row4(7); + row4 << 0, 0, 0, 0, 1 - .015, .015, .0; + ASSERT_EQ(mat.row(4), row4); + + Eigen::RowVectorXd row5(7); + row5 << 0, 0, 0, 0, .014, 1 - .014, .0; + ASSERT_EQ(mat.row(5), row5); + + Eigen::RowVectorXd row6(7); + row6 << 0, 0, 0, 0, .014, .015, 1 - (.014 + .015); + ASSERT_EQ(mat.row(6), row6); +} + + +TEST_F(EtQubitTest, addErrorX) { + EXPECT_FALSE(qubit->has_x_error); + qubit->addErrorX(); + EXPECT_TRUE(qubit->has_x_error); + qubit->addErrorX(); + EXPECT_FALSE(qubit->has_x_error); +} + +TEST_F(EtQubitTest, addErrorZ) { + EXPECT_FALSE(qubit->has_z_error); + qubit->addErrorZ(); + EXPECT_TRUE(qubit->has_z_error); + qubit->addErrorZ(); + EXPECT_FALSE(qubit->has_z_error); +} } // namespace diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index 5d2ac0462..100672be0 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -64,6 +64,7 @@ class Qubit : public ErrorTrackingQubit { using ErrorTrackingQubit::localMeasureZ; using ErrorTrackingQubit::measureDensityIndependent; using ErrorTrackingQubit::measurement_err; + using ErrorTrackingQubit::memory_transition_matrix; using ErrorTrackingQubit::setMemoryErrorRates; using ErrorTrackingQubit::updated_time; diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index c4599fe3a..161670b45 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -103,52 +103,6 @@ class StatQubitTest : public ::testing::Test { MockQuantumBackend *backend; }; -// TEST(StatQubitTest, initialize_memory_transition_matrix) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// setParDouble(qubit, "memory_X_error_rate", .011); -// setParDouble(qubit, "memory_Y_error_rate", .012); -// setParDouble(qubit, "memory_Z_error_rate", .013); -// setParDouble(qubit, "memory_energy_excitation_rate", .014); -// setParDouble(qubit, "memory_energy_relaxation_rate", .015); -// setParDouble(qubit, "memory_completely_mixed_rate", 0); -// sim->registerComponent(qubit); -// qubit->callInitialize(); - -// auto mat = qubit->Memory_Transition_matrix; - -// // each element means: "Clean Xerror Zerror Yerror Excited Relaxed Mixed" -// Eigen::RowVectorXd row0(7); -// double sigma = .011 + .013 + .012 + .014 + .015; -// row0 << 1 - sigma, .011, .013, .012, .014, .015, .0; -// ASSERT_EQ(mat.row(0), row0); - -// Eigen::RowVectorXd row1(7); -// row1 << .011, 1 - sigma, .012, .013, .014, .015, .0; -// ASSERT_EQ(mat.row(1), row1); - -// Eigen::RowVectorXd row2(7); -// row2 << .013, .012, 1 - sigma, .011, .014, .015, .0; -// ASSERT_EQ(mat.row(2), row2); - -// Eigen::RowVectorXd row3(7); -// row3 << .012, .013, .011, 1 - sigma, .014, .015, .0; -// ASSERT_EQ(mat.row(3), row3); - -// Eigen::RowVectorXd row4(7); -// row4 << 0, 0, 0, 0, 1 - .015, .015, .0; -// ASSERT_EQ(mat.row(4), row4); - -// Eigen::RowVectorXd row5(7); -// row5 << 0, 0, 0, 0, .014, 1 - .014, .0; -// ASSERT_EQ(mat.row(5), row5); - -// Eigen::RowVectorXd row6(7); -// row6 << 0, 0, 0, 0, .014, .015, 1 - (.014 + .015); -// ASSERT_EQ(mat.row(6), row6); -// } - TEST_F(StatQubitTest, init) { auto *backend_qubit = new MockBackendQubit(); auto *config = new IConfiguration(); @@ -159,28 +113,4 @@ TEST_F(StatQubitTest, init) { delete backend_qubit; } -// TEST(StatQubitTest, addXError) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// sim->registerComponent(qubit); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// qubit->addXerror(); -// EXPECT_TRUE(qubit->par("GOD_Xerror")); -// qubit->addXerror(); -// EXPECT_FALSE(qubit->par("GOD_Xerror")); -// } - -// TEST(StatQubitTest, addZError) { -// auto *sim = prepareSimulation(); -// auto *qubit = new StatQubitTarget{}; -// qubit->fillParams(); -// sim->registerComponent(qubit); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// qubit->addZerror(); -// EXPECT_TRUE(qubit->par("GOD_Zerror")); -// qubit->addZerror(); -// EXPECT_FALSE(qubit->par("GOD_Zerror")); -// } - } // namespace From 6ab455eeba1de720d4975406ab4224e1ec4368d5 Mon Sep 17 00:00:00 2001 From: zigen Date: Sun, 17 Apr 2022 12:41:39 +0900 Subject: [PATCH 20/43] cleanup StationaryQubit --- quisp/backends/ErrorTracking/Qubit_test.cc | 1 - .../QNIC/StationaryQubit/IStationaryQubit.h | 57 +------------------ .../QNIC/StationaryQubit/StationaryQubit.cc | 39 ++++--------- .../QNIC/StationaryQubit/StationaryQubit.h | 8 ++- .../StationaryQubit/StationaryQubit_test.cc | 6 +- quisp/test_utils/mock_modules/MockQubit.h | 10 +--- 6 files changed, 20 insertions(+), 101 deletions(-) diff --git a/quisp/backends/ErrorTracking/Qubit_test.cc b/quisp/backends/ErrorTracking/Qubit_test.cc index 34914b5dd..66cc5487d 100644 --- a/quisp/backends/ErrorTracking/Qubit_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_test.cc @@ -159,7 +159,6 @@ TEST_F(EtQubitTest, initialize_memory_transition_matrix) { ASSERT_EQ(mat.row(6), row6); } - TEST_F(EtQubitTest, addErrorX) { EXPECT_FALSE(qubit->has_x_error); qubit->addErrorX(); diff --git a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h index 8e16aff43..1fdaa92a6 100644 --- a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h @@ -44,34 +44,6 @@ enum class CliffordOperator : int { } // namespace types namespace modules { -struct emission_error_model { - double pauli_error_rate; // Overall error rate - double Z_error_rate; - double X_error_rate; - double Y_error_rate; - double Loss_error_rate; - - double No_error_ceil; - double X_error_ceil; - double Y_error_ceil; - double Z_error_ceil; - double Loss_error_ceil; -}; - -struct MeasurementErrorModel { - double x_error_rate; - double y_error_rate; - double z_error_rate; -}; - -struct GodErrorState { - bool has_x_error = false; - bool has_z_error = false; - bool has_excitation_error = false; - bool has_relaxation_error = false; - bool has_completely_mixed_error = false; -}; - // Matrices of single qubit errors. Used when conducting tomography. struct single_qubit_error { Eigen::Matrix2cd X; // double 2*2 matrix @@ -138,39 +110,12 @@ class IStationaryQubit : public omnetpp::cSimpleModule { virtual backends::IQubit *getEntangledPartner() const = 0; virtual backends::IQubit *getBackendQubitRef() const = 0; virtual int getPartnerStationaryQubitAddress() const = 0; + virtual void assertEntangledPartnerValid() = 0; - int stationaryQubit_address; - int node_address; int qnic_address; int qnic_type; int qnic_index; - int god_entangled_stationary_qubit_address; - int god_entangled_node_address; - int god_entangled_qnic_address; - int god_entangled_qnic_type; - int action_index; - bool no_density_matrix_nullptr_entangled_partner_ok; - - virtual void assertEntangledPartnerValid() = 0; - - /** Photon emitted at*/ - omnetpp::simtime_t emitted_time = -1; - // internal - /** Stationary qubit last updated at*/ - omnetpp::simtime_t updated_time = -1; - - /** Standard deviation */ - double emission_jittering_standard_deviation; - - SingleGateErrorModel Hgate_error; - SingleGateErrorModel Xgate_error; - SingleGateErrorModel Zgate_error; - TwoQubitGateErrorModel CNOTgate_error; - MeasurementErrorModel Measurement_error; - - Eigen::Matrix2cd Density_Matrix_Collapsed; // Used when partner has been measured. }; - } // namespace modules } // namespace quisp diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index d281ed79b..eaaba568f 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -68,7 +68,6 @@ void StationaryQubit::initialize() { // watch variables to show them in the GUI WATCH(emitted_time); - WATCH(updated_time); WATCH(is_busy); } @@ -160,7 +159,6 @@ void StationaryQubit::CNOT_gate(IStationaryQubit *control_qubit) { qubit_ref->ga void StationaryQubit::setBusy() { is_busy = true; emitted_time = simTime(); - updated_time = simTime(); // Should be no error at this time. if (hasGUI()) { getDisplayString().setTagArg("i", 1, "red"); } @@ -176,34 +174,17 @@ void StationaryQubit::setFree(bool consumed) { locked_rule_id = -1; action_index = -1; emitted_time = -1; - updated_time = simTime(); - - /* - - - - - par("photon_emitted_at") = emitted_time.dbl(); - par("last_updated_at") = updated_time.dbl(); - par("GOD_Xerror") = false; - par("GOD_Zerror") = false; - par("GOD_CMerror") = false; - par("GOD_EXerror") = false; - par("GOD_REerror") = false; - par("GOD_CMerror") = false; - par("isBusy") = false; - EV_DEBUG << "Freeing this qubit!!!" << this << " at qnode: " << node_address << " qnic_type: " << qnic_type << " qnic_index: " << qnic_index << "\n"; - // GUI part - if (hasGUI()) { - if (consumed) { - bubble("Consumed!"); - getDisplayString().setTagArg("i", 1, "yellow"); - } else { - bubble("Failed to entangle!"); - getDisplayString().setTagArg("i", 1, "blue"); - } + + EV_DEBUG << "Freeing this qubit! " << this << " at qnode: " << node_address << " qnic_type: " << qnic_type << " qnic_index: " << qnic_index << "\n"; + if (hasGUI()) { + if (consumed) { + bubble("Consumed!"); + getDisplayString().setTagArg("i", 1, "yellow"); + } else { + bubble("Failed to entangle!"); + getDisplayString().setTagArg("i", 1, "blue"); } - */ + } } backends::IQubit *StationaryQubit::getEntangledPartner() const { return qubit_ref->getEntangledPartner(); } diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index 2851ed203..90f28aaf8 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -169,11 +169,17 @@ class StationaryQubit : public IStationaryQubit { * if you want to use different qubit configuration, it's useful. */ std::unique_ptr prepareBackendQubitConfiguration(bool overwrite); - void tryToAssignParDouble(double &field, const char *par_name); // this is for debugging. class internal use only. // and it's different from QubitRecord's one. bool is_busy; + // photon emitted at + omnetpp::simtime_t emitted_time = -1; + // Standard deviation + double emission_jittering_standard_deviation; + int stationaryQubit_address; + int node_address; + utils::ComponentProvider provider; IQuantumBackend *backend; }; diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 161670b45..c2b3aa732 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -34,11 +34,7 @@ class StatQubitTarget : public StationaryQubit { setComponentType(new TestModuleType("test qubit")); provider.setStrategy(std::make_unique(backend)); } - void reset() { - setFree(true); - updated_time = SimTime(0); - no_density_matrix_nullptr_entangled_partner_ok = true; - } + void reset() { setFree(true); } void fillParams() { // see networks/omnetpp.ini setParDouble(this, "emission_success_probability", 0.5); diff --git a/quisp/test_utils/mock_modules/MockQubit.h b/quisp/test_utils/mock_modules/MockQubit.h index 8ba9f4511..f7bef609b 100644 --- a/quisp/test_utils/mock_modules/MockQubit.h +++ b/quisp/test_utils/mock_modules/MockQubit.h @@ -64,11 +64,7 @@ class MockQubit : public IStationaryQubit { qnic_type = _type; qnic_index = _qnic_index; } - void reset() { - setFree(true); - updated_time = SimTime(0); - no_density_matrix_nullptr_entangled_partner_ok = true; - } + void reset() { setFree(true); } void fillParams() { // see networks/omnetpp.ini setParDouble(this, "emission_success_probability", 0.5); @@ -122,10 +118,6 @@ class MockQubit : public IStationaryQubit { setParBool(this, "god_excitation_error", false); setParBool(this, "god_relaxation_error", false); setParBool(this, "is_busy", false); - setParInt(this, "god_entangled_stationary_qubit_address", 0); - setParInt(this, "god_entangled_node_address", 0); - setParInt(this, "god_entangled_qnic_address", 0); - setParInt(this, "god_entangled_qnic_type", 0); setParDouble(this, "fidelity", -1.0); } }; From 586eedd319d282db930ac4a58ea4aca50fedeb14 Mon Sep 17 00:00:00 2001 From: zigen Date: Thu, 16 Jun 2022 20:41:45 +0900 Subject: [PATCH 21/43] fix StatQubit test --- quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index c2b3aa732..dfbdb5c60 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -100,11 +100,13 @@ class StatQubitTest : public ::testing::Test { }; TEST_F(StatQubitTest, init) { + auto *sim = utils::prepareSimulation(); auto *backend_qubit = new MockBackendQubit(); auto *config = new IConfiguration(); EXPECT_CALL(*backend, getDefaultConfiguration()).WillOnce(Return(ByMove(std::unique_ptr(config)))); EXPECT_CALL(*backend, getQubit(NotNull(), NotNull())).WillOnce(Return(backend_qubit)); EXPECT_CALL(*backend_qubit, setFree()).WillOnce(Return()); + sim->registerComponent(qubit); qubit->callInitialize(); delete backend_qubit; } From 2fa9bbceb127f916d8c47517dd76e2ce76a062ad Mon Sep 17 00:00:00 2001 From: zigen Date: Tue, 21 Jun 2022 19:01:34 +0900 Subject: [PATCH 22/43] add more tests for EtQubit --- quisp/backends/ErrorTracking/Qubit_test.cc | 6 ++++++ quisp/backends/ErrorTracking/test.h | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/quisp/backends/ErrorTracking/Qubit_test.cc b/quisp/backends/ErrorTracking/Qubit_test.cc index 66cc5487d..ccc2f84b4 100644 --- a/quisp/backends/ErrorTracking/Qubit_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_test.cc @@ -174,4 +174,10 @@ TEST_F(EtQubitTest, addErrorZ) { qubit->addErrorZ(); EXPECT_FALSE(qubit->has_z_error); } + +TEST_F(EtQubitTest, backend_mock) { + auto* qubit = backend->getQubit(1); + auto* another_qubit = backend->getQubit(1); + ASSERT_EQ(qubit, another_qubit); +} } // namespace diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index 100672be0..1b9a9e22d 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -81,7 +81,6 @@ class Backend : public ErrorTrackingBackend { using ErrorTrackingBackend::qubits; Backend(std::unique_ptr rng, std::unique_ptr config) : ErrorTrackingBackend(std::move(rng), std::move(config)) {} IQubit* getQubit(int id) { return this->getQubitInternal(new QubitId(id)); } - IQubit* getQubit(const IQubitId* id) override { throw std::runtime_error("do not call IQubit* getQubit(const IQubitId* id) in this test"); } IQubit* getQubitInternal(const IQubitId* id) { auto qubit = qubits.find(id); From 2e637fad52bde9c19ef602469e354837141073e0 Mon Sep 17 00:00:00 2001 From: zigen Date: Wed, 22 Jun 2022 11:57:59 +0900 Subject: [PATCH 23/43] add test for StationaryQubit::finish, prepareBackendQubitConfiguration --- ...aryQubit_internal_stabilizer_graph_test.cc | 2 +- .../StationaryQubit/StationaryQubit_test.cc | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_internal_stabilizer_graph_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_internal_stabilizer_graph_test.cc index 3f565c1c4..2d265146a 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_internal_stabilizer_graph_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_internal_stabilizer_graph_test.cc @@ -635,4 +635,4 @@ TEST(StatQubitInternalGraphTest, graphMeasureZGHZState) { } } } -} // end namespace \ No newline at end of file +} // end namespace diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index dfbdb5c60..cde034954 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -7,6 +7,8 @@ #include #include "backends/interfaces/IConfiguration.h" #include "backends/interfaces/IQuantumBackend.h" +#include "omnetpp/cmessage.h" +#include "test_utils/Simulation.h" #include "test_utils/UtilFunctions.h" #include "test_utils/mock_backends/MockQuantumBackend.h" @@ -28,8 +30,11 @@ class Strategy : public TestComponentProviderStrategy { class StatQubitTarget : public StationaryQubit { public: + using StationaryQubit::backend; + using StationaryQubit::finish; using StationaryQubit::initialize; using StationaryQubit::par; + using StationaryQubit::prepareBackendQubitConfiguration; StatQubitTarget(IQuantumBackend *backend) : StationaryQubit() { setComponentType(new TestModuleType("test qubit")); provider.setStrategy(std::make_unique(backend)); @@ -88,27 +93,41 @@ class StatQubitTarget : public StationaryQubit { class StatQubitTest : public ::testing::Test { protected: void SetUp() { - prepareSimulation(); + sim = prepareSimulation(); backend = new MockQuantumBackend(); qubit = new StatQubitTarget(backend); qubit->fillParams(); + sim->registerComponent(qubit); } void TearDown() { delete backend; } StatQubitTarget *qubit; MockQuantumBackend *backend; + simulation::TestSimulation *sim; }; TEST_F(StatQubitTest, init) { - auto *sim = utils::prepareSimulation(); auto *backend_qubit = new MockBackendQubit(); auto *config = new IConfiguration(); EXPECT_CALL(*backend, getDefaultConfiguration()).WillOnce(Return(ByMove(std::unique_ptr(config)))); EXPECT_CALL(*backend, getQubit(NotNull(), NotNull())).WillOnce(Return(backend_qubit)); EXPECT_CALL(*backend_qubit, setFree()).WillOnce(Return()); - sim->registerComponent(qubit); qubit->callInitialize(); delete backend_qubit; } +TEST_F(StatQubitTest, prepareBackendQubit) { + auto *config = new IConfiguration(); + + // usually qubit->backend is assigned during initialize() + qubit->backend = backend; + + EXPECT_CALL(*backend, getDefaultConfiguration()).WillOnce(Return(ByMove(std::unique_ptr(config)))); + qubit->prepareBackendQubitConfiguration(true); +} + +TEST_F(StatQubitTest, finish) { + ASSERT_NO_THROW({ qubit->finish(); }); +} + } // namespace From 1cd5647d756b8a0857003473c72563534904cfdd Mon Sep 17 00:00:00 2001 From: zigen Date: Thu, 23 Jun 2022 20:10:36 +0900 Subject: [PATCH 24/43] add tests for StationaryQubit::handleMessage --- .../StationaryQubit/StationaryQubit_test.cc | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index cde034954..0a0db963a 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -4,6 +4,10 @@ #include #include #include +#include +#include +#include +#include #include #include "backends/interfaces/IConfiguration.h" #include "backends/interfaces/IQuantumBackend.h" @@ -17,6 +21,7 @@ using namespace quisp::modules; using namespace quisp::modules::common; using namespace quisp_test; using namespace Eigen; +using namespace omnetpp; namespace { @@ -32,12 +37,14 @@ class StatQubitTarget : public StationaryQubit { public: using StationaryQubit::backend; using StationaryQubit::finish; + using StationaryQubit::handleMessage; using StationaryQubit::initialize; using StationaryQubit::par; using StationaryQubit::prepareBackendQubitConfiguration; StatQubitTarget(IQuantumBackend *backend) : StationaryQubit() { setComponentType(new TestModuleType("test qubit")); provider.setStrategy(std::make_unique(backend)); + toLensGate = new TestGate(this, "tolens_quantum_port$o"); } void reset() { setFree(true); } void fillParams() { @@ -88,6 +95,14 @@ class StatQubitTarget : public StationaryQubit { setParDouble(this, "emission_jittering_standard_deviation", 0.5); setParBool(this, "overwrite_backend_qubit_config", false); } + + TestGate *toLensGate; + cGate *gate(const char *gatename, int index = -1) override { + if (strcmp("tolens_quantum_port$o", gatename) != 0) { + throw std::runtime_error("unexpected gate name"); + } + return toLensGate; + } }; class StatQubitTest : public ::testing::Test { @@ -126,6 +141,37 @@ TEST_F(StatQubitTest, prepareBackendQubit) { qubit->prepareBackendQubitConfiguration(true); } +TEST_F(StatQubitTest, emissionFailedPhotonLost) { + sim->setContext(qubit); + auto *msg = new PhotonicQubit(); + qubit->emission_success_probability = 0; + EXPECT_EQ(qubit->toLensGate->messages.size(), 0); + qubit->handleMessage(msg); + EXPECT_EQ(qubit->toLensGate->messages.size(), 1); + auto *new_msg = qubit->toLensGate->messages.at(0); + ASSERT_NE(new_msg, nullptr); + EXPECT_NE(new_msg, msg); + + auto *photon = dynamic_cast(new_msg); + ASSERT_NE(photon, nullptr); + EXPECT_TRUE(photon->getPhotonLost()); +} + +TEST_F(StatQubitTest, emissionSuccess) { + sim->setContext(qubit); + auto *msg = new PhotonicQubit(); + qubit->emission_success_probability = 1; + EXPECT_EQ(qubit->toLensGate->messages.size(), 0); + qubit->handleMessage(msg); + EXPECT_EQ(qubit->toLensGate->messages.size(), 1); + auto *new_msg = qubit->toLensGate->messages.at(0); + ASSERT_NE(new_msg, nullptr); + + auto *photon = dynamic_cast(new_msg); + ASSERT_NE(photon, nullptr); + EXPECT_FALSE(photon->getPhotonLost()); +} + TEST_F(StatQubitTest, finish) { ASSERT_NO_THROW({ qubit->finish(); }); } From 5a78100ef62f9e0b8f050bde830ad462edf6b5dc Mon Sep 17 00:00:00 2001 From: zigen Date: Thu, 23 Jun 2022 20:24:35 +0900 Subject: [PATCH 25/43] fix: remove include --- quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 0a0db963a..7ea140e2f 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include "backends/interfaces/IConfiguration.h" From e285d86d4a9a8968a908d888d156f20276215ad2 Mon Sep 17 00:00:00 2001 From: zigen Date: Fri, 24 Jun 2022 13:16:15 +0900 Subject: [PATCH 26/43] add EtQubitConfigration test --- .../StationaryQubit/StationaryQubit_test.cc | 119 +++++++++++++++++- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 7ea140e2f..1f556358c 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -8,6 +8,8 @@ #include #include #include +#include "backends/Backends.h" +#include "backends/ErrorTracking/Configuration.h" #include "backends/interfaces/IConfiguration.h" #include "backends/interfaces/IQuantumBackend.h" #include "omnetpp/cmessage.h" @@ -21,6 +23,7 @@ using namespace quisp::modules::common; using namespace quisp_test; using namespace Eigen; using namespace omnetpp; +using quisp::backends::ErrorTrackingConfiguration; namespace { @@ -130,14 +133,124 @@ TEST_F(StatQubitTest, init) { delete backend_qubit; } -TEST_F(StatQubitTest, prepareBackendQubit) { - auto *config = new IConfiguration(); +TEST_F(StatQubitTest, errorTrackingQubitConfigurationOverwrite) { + auto *config = new ErrorTrackingConfiguration(); + setParDouble(qubit, "CNOTgate_error_rate", 0.01); + setParDouble(qubit, "CNOTgate_IX_error_ratio", 0.02); + setParDouble(qubit, "CNOTgate_XI_error_ratio", 0.03); + setParDouble(qubit, "CNOTgate_XX_error_ratio", 0.04); + setParDouble(qubit, "CNOTgate_IZ_error_ratio", 0.05); + setParDouble(qubit, "CNOTgate_ZI_error_ratio", 0.06); + setParDouble(qubit, "CNOTgate_ZZ_error_ratio", 0.07); + setParDouble(qubit, "CNOTgate_IY_error_ratio", 0.08); + setParDouble(qubit, "CNOTgate_YI_error_ratio", 0.09); + setParDouble(qubit, "CNOTgate_YY_error_ratio", 0.10); + + setParDouble(qubit, "Hgate_error_rate", 0.11); + setParDouble(qubit, "Hgate_X_error_ratio", 0.12); + setParDouble(qubit, "Hgate_Y_error_ratio", 0.13); + setParDouble(qubit, "Hgate_Z_error_ratio", 0.14); + + setParDouble(qubit, "Xgate_error_rate", 0.15); + setParDouble(qubit, "Xgate_X_error_ratio", 0.16); + setParDouble(qubit, "Xgate_Y_error_ratio", 0.17); + setParDouble(qubit, "Xgate_Z_error_ratio", 0.18); + + setParDouble(qubit, "Zgate_error_rate", 0.19); + setParDouble(qubit, "Zgate_X_error_ratio", 0.20); + setParDouble(qubit, "Zgate_Y_error_ratio", 0.21); + setParDouble(qubit, "Zgate_Z_error_ratio", 0.22); + + setParDouble(qubit, "X_measurement_error_rate", 0.23); + setParDouble(qubit, "Y_measurement_error_rate", 0.24); + setParDouble(qubit, "Z_measurement_error_rate", 0.25); + + setParDouble(qubit, "memory_X_error_rate", 0.26); + setParDouble(qubit, "memory_Y_error_rate", 0.27); + setParDouble(qubit, "memory_Z_error_rate", 0.28); + setParDouble(qubit, "memory_energy_excitation_rate", 0.29); + setParDouble(qubit, "memory_energy_relaxation_rate", 0.30); + setParDouble(qubit, "memory_completely_mixed_rate", 0.31); + + EXPECT_NE(config->cnot_gate_err_rate, qubit->par("CNOTgate_error_rate").doubleValue()); + EXPECT_NE(config->cnot_gate_ix_err_ratio, qubit->par("CNOTgate_IX_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_xi_err_ratio, qubit->par("CNOTgate_XI_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_xx_err_ratio, qubit->par("CNOTgate_XX_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_iz_err_ratio, qubit->par("CNOTgate_IZ_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_zi_err_ratio, qubit->par("CNOTgate_ZI_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_zz_err_ratio, qubit->par("CNOTgate_ZZ_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_iy_err_ratio, qubit->par("CNOTgate_IY_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_yi_err_ratio, qubit->par("CNOTgate_YI_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_yy_err_ratio, qubit->par("CNOTgate_YY_error_ratio").doubleValue()); + + EXPECT_NE(config->h_gate_err_rate, qubit->par("Hgate_error_rate").doubleValue()); + EXPECT_NE(config->h_gate_x_err_ratio, qubit->par("Hgate_X_error_ratio").doubleValue()); + EXPECT_NE(config->h_gate_y_err_ratio, qubit->par("Hgate_Y_error_ratio").doubleValue()); + EXPECT_NE(config->h_gate_z_err_ratio, qubit->par("Hgate_Z_error_ratio").doubleValue()); + + EXPECT_NE(config->x_gate_err_rate, qubit->par("Xgate_error_rate").doubleValue()); + EXPECT_NE(config->x_gate_x_err_ratio, qubit->par("Xgate_X_error_ratio").doubleValue()); + EXPECT_NE(config->x_gate_y_err_ratio, qubit->par("Xgate_Y_error_ratio").doubleValue()); + EXPECT_NE(config->x_gate_z_err_ratio, qubit->par("Xgate_Z_error_ratio").doubleValue()); + + EXPECT_NE(config->z_gate_err_rate, qubit->par("Zgate_error_rate").doubleValue()); + EXPECT_NE(config->z_gate_x_err_ratio, qubit->par("Zgate_X_error_ratio").doubleValue()); + EXPECT_NE(config->z_gate_y_err_ratio, qubit->par("Zgate_Y_error_ratio").doubleValue()); + EXPECT_NE(config->z_gate_z_err_ratio, qubit->par("Zgate_Z_error_ratio").doubleValue()); + + EXPECT_NE(config->measurement_x_err_rate, qubit->par("X_measurement_error_rate").doubleValue()); + EXPECT_NE(config->measurement_y_err_rate, qubit->par("Y_measurement_error_rate").doubleValue()); + EXPECT_NE(config->measurement_z_err_rate, qubit->par("Z_measurement_error_rate").doubleValue()); + + EXPECT_NE(config->memory_x_err_rate, qubit->par("memory_X_error_rate").doubleValue()); + EXPECT_NE(config->memory_y_err_rate, qubit->par("memory_Y_error_rate").doubleValue()); + EXPECT_NE(config->memory_z_err_rate, qubit->par("memory_Z_error_rate").doubleValue()); + EXPECT_NE(config->memory_excitation_rate, qubit->par("memory_energy_excitation_rate").doubleValue()); + EXPECT_NE(config->memory_relaxation_rate, qubit->par("memory_energy_relaxation_rate").doubleValue()); + EXPECT_NE(config->memory_completely_mixed_rate, qubit->par("memory_completely_mixed_rate").doubleValue()); // usually qubit->backend is assigned during initialize() qubit->backend = backend; EXPECT_CALL(*backend, getDefaultConfiguration()).WillOnce(Return(ByMove(std::unique_ptr(config)))); - qubit->prepareBackendQubitConfiguration(true); + auto new_conf = qubit->prepareBackendQubitConfiguration(true); + + EXPECT_EQ(config->cnot_gate_err_rate, qubit->par("CNOTgate_error_rate").doubleValue()); + EXPECT_EQ(config->cnot_gate_ix_err_ratio, qubit->par("CNOTgate_IX_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_xi_err_ratio, qubit->par("CNOTgate_XI_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_xx_err_ratio, qubit->par("CNOTgate_XX_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_iz_err_ratio, qubit->par("CNOTgate_IZ_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_zi_err_ratio, qubit->par("CNOTgate_ZI_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_zz_err_ratio, qubit->par("CNOTgate_ZZ_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_iy_err_ratio, qubit->par("CNOTgate_IY_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_yi_err_ratio, qubit->par("CNOTgate_YI_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_yy_err_ratio, qubit->par("CNOTgate_YY_error_ratio").doubleValue()); + + EXPECT_EQ(config->h_gate_err_rate, qubit->par("Hgate_error_rate").doubleValue()); + EXPECT_EQ(config->h_gate_x_err_ratio, qubit->par("Hgate_X_error_ratio").doubleValue()); + EXPECT_EQ(config->h_gate_y_err_ratio, qubit->par("Hgate_Y_error_ratio").doubleValue()); + EXPECT_EQ(config->h_gate_z_err_ratio, qubit->par("Hgate_Z_error_ratio").doubleValue()); + + EXPECT_EQ(config->x_gate_err_rate, qubit->par("Xgate_error_rate").doubleValue()); + EXPECT_EQ(config->x_gate_x_err_ratio, qubit->par("Xgate_X_error_ratio").doubleValue()); + EXPECT_EQ(config->x_gate_y_err_ratio, qubit->par("Xgate_Y_error_ratio").doubleValue()); + EXPECT_EQ(config->x_gate_z_err_ratio, qubit->par("Xgate_Z_error_ratio").doubleValue()); + + EXPECT_EQ(config->z_gate_err_rate, qubit->par("Zgate_error_rate").doubleValue()); + EXPECT_EQ(config->z_gate_x_err_ratio, qubit->par("Zgate_X_error_ratio").doubleValue()); + EXPECT_EQ(config->z_gate_y_err_ratio, qubit->par("Zgate_Y_error_ratio").doubleValue()); + EXPECT_EQ(config->z_gate_z_err_ratio, qubit->par("Zgate_Z_error_ratio").doubleValue()); + + EXPECT_EQ(config->measurement_x_err_rate, qubit->par("X_measurement_error_rate").doubleValue()); + EXPECT_EQ(config->measurement_y_err_rate, qubit->par("Y_measurement_error_rate").doubleValue()); + EXPECT_EQ(config->measurement_z_err_rate, qubit->par("Z_measurement_error_rate").doubleValue()); + + EXPECT_EQ(config->memory_x_err_rate, qubit->par("memory_X_error_rate").doubleValue()); + EXPECT_EQ(config->memory_y_err_rate, qubit->par("memory_Y_error_rate").doubleValue()); + EXPECT_EQ(config->memory_z_err_rate, qubit->par("memory_Z_error_rate").doubleValue()); + EXPECT_EQ(config->memory_excitation_rate, qubit->par("memory_energy_excitation_rate").doubleValue()); + EXPECT_EQ(config->memory_relaxation_rate, qubit->par("memory_energy_relaxation_rate").doubleValue()); + EXPECT_EQ(config->memory_completely_mixed_rate, qubit->par("memory_completely_mixed_rate").doubleValue()); } TEST_F(StatQubitTest, emissionFailedPhotonLost) { From 5befc62d88aecf049d0a3fe13be3d14e99386d2e Mon Sep 17 00:00:00 2001 From: zigen Date: Fri, 24 Jun 2022 13:29:28 +0900 Subject: [PATCH 27/43] add tests for backend container --- quisp/modules/Backend/Backend_test.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/quisp/modules/Backend/Backend_test.cc b/quisp/modules/Backend/Backend_test.cc index 9434552d5..01b020867 100644 --- a/quisp/modules/Backend/Backend_test.cc +++ b/quisp/modules/Backend/Backend_test.cc @@ -1,6 +1,7 @@ #include "Backend.h" #include #include +#include "backends/interfaces/IQuantumBackend.h" #include "modules/common_types.h" namespace { @@ -86,6 +87,12 @@ TEST_F(BackendContainerTest, getQuantumBackend) { EXPECT_NE(et_backend, nullptr); } +TEST_F(BackendContainerTest, getQuantumBackendWithoutInit) { + setParStr(backend, "backendType", "ErrorTrackingBackend"); + ASSERT_EQ(backend->backend, nullptr); + EXPECT_ANY_THROW({ backend->getQuantumBackend(); }); +} + TEST_F(BackendContainerTest, getBackendConfiguration) { setParStr(backend, "backendType", "ErrorTrackingBackend"); backend->callInitialize(); @@ -119,4 +126,8 @@ TEST_F(BackendContainerTest, getCopyOfBackendConfiguration) { EXPECT_NE(et_conf->cnot_gate_err_rate, et_conf2->cnot_gate_err_rate); EXPECT_NE(et_conf, et_conf2); } + +TEST_F(BackendContainerTest, finish) { + EXPECT_NO_THROW({ backend->finish(); }); +} } // namespace From f1320d1b432b6298cb7571a33e4d1779c9e498ca Mon Sep 17 00:00:00 2001 From: soon Date: Sat, 7 Jan 2023 14:56:14 +0000 Subject: [PATCH 28/43] rename stationaryQubit_address to stationary_qubit_address --- quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc | 2 +- quisp/modules/QNIC/StationaryQubit/StationaryQubit.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index eaaba568f..e884276bd 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -62,7 +62,7 @@ void StationaryQubit::initialize() { backend = provider.getQuantumBackend(); auto config = prepareBackendQubitConfiguration(par("overwrite_backend_qubit_config").boolValue()); - qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationaryQubit_address), std::move(config)); + qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationary_qubit_address), std::move(config)); if (qubit_ref == nullptr) throw std::runtime_error("qubit_ref nullptr error"); setFree(false); diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index 90f28aaf8..7128b2726 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -177,7 +177,7 @@ class StationaryQubit : public IStationaryQubit { omnetpp::simtime_t emitted_time = -1; // Standard deviation double emission_jittering_standard_deviation; - int stationaryQubit_address; + int stationary_qubit_address; int node_address; utils::ComponentProvider provider; From 500b04fc4cc1d149eca13e3f907032d61a7065ca Mon Sep 17 00:00:00 2001 From: soon Date: Sat, 7 Jan 2023 15:42:05 +0000 Subject: [PATCH 29/43] normalize left over ned parameters to snake case --- quisp/modules/Backend/Backend.cc | 8 +- quisp/modules/Backend/Backend.ned | 2 +- quisp/modules/Backend/Backend_test.cc | 12 +- .../StationaryQubit/StationaryQubit_test.cc | 198 +++++++++--------- 4 files changed, 110 insertions(+), 110 deletions(-) diff --git a/quisp/modules/Backend/Backend.cc b/quisp/modules/Backend/Backend.cc index 67958775e..24d4e3336 100644 --- a/quisp/modules/Backend/Backend.cc +++ b/quisp/modules/Backend/Backend.cc @@ -8,7 +8,7 @@ BackendContainer::BackendContainer() {} BackendContainer::~BackendContainer() {} void BackendContainer::initialize() { - auto backend_type = std::string(par("backendType").stringValue()); + auto backend_type = std::string(par("backend_type").stringValue()); if (backend_type == "ErrorTrackingBackend") { configureErrorTrackingBackend(); } else { @@ -23,9 +23,9 @@ void BackendContainer::configureErrorTrackingBackend() { conf->measurement_z_err_rate = par("z_measurement_error_rate").doubleValue(); conf->h_gate_err_rate = par("h_gate_error_rate").doubleValue(); - conf->h_gate_x_err_ratio = par("h_gate_X_error_ratio").doubleValue(); - conf->h_gate_y_err_ratio = par("h_gate_Y_error_ratio").doubleValue(); - conf->h_gate_z_err_ratio = par("h_gate_Z_error_ratio").doubleValue(); + conf->h_gate_x_err_ratio = par("h_gate_x_error_ratio").doubleValue(); + conf->h_gate_y_err_ratio = par("h_gate_y_error_ratio").doubleValue(); + conf->h_gate_z_err_ratio = par("h_gate_z_error_ratio").doubleValue(); conf->x_gate_err_rate = par("x_gate_error_rate").doubleValue(); conf->x_gate_x_err_ratio = par("x_gate_x_error_ratio").doubleValue(); diff --git a/quisp/modules/Backend/Backend.ned b/quisp/modules/Backend/Backend.ned index 3bbf4cf36..16a8b0bcf 100644 --- a/quisp/modules/Backend/Backend.ned +++ b/quisp/modules/Backend/Backend.ned @@ -6,7 +6,7 @@ simple Backend parameters: @class(BackendContainer); @display("p=30,40;"); - string backendType = default("ErrorTrackingBackend"); + string backend_type = default("ErrorTrackingBackend"); // ErrorTracking Backend Configurations // characteristics of the hardware diff --git a/quisp/modules/Backend/Backend_test.cc b/quisp/modules/Backend/Backend_test.cc index 01b020867..13f3575f8 100644 --- a/quisp/modules/Backend/Backend_test.cc +++ b/quisp/modules/Backend/Backend_test.cc @@ -65,20 +65,20 @@ class BackendContainerTest : public ::testing::Test { TEST_F(BackendContainerTest, constructor) { BackendContainer backend; } TEST_F(BackendContainerTest, callInitialize) { - setParStr(backend, "backendType", "ErrorTrackingBackend"); + setParStr(backend, "backend_type", "ErrorTrackingBackend"); EXPECT_EQ(backend->backend, nullptr); backend->callInitialize(); EXPECT_NE(backend->backend, nullptr); } TEST_F(BackendContainerTest, callInitializeWithInvalidBackend) { - setParStr(backend, "backendType", "SomeInvalidBackend"); + setParStr(backend, "backend_type", "SomeInvalidBackend"); EXPECT_EQ(backend->backend, nullptr); EXPECT_THROW(backend->callInitialize(), omnetpp::cRuntimeError); } TEST_F(BackendContainerTest, getQuantumBackend) { - setParStr(backend, "backendType", "ErrorTrackingBackend"); + setParStr(backend, "backend_type", "ErrorTrackingBackend"); backend->callInitialize(); ASSERT_NE(backend->backend, nullptr); auto *b = backend->getQuantumBackend(); @@ -88,13 +88,13 @@ TEST_F(BackendContainerTest, getQuantumBackend) { } TEST_F(BackendContainerTest, getQuantumBackendWithoutInit) { - setParStr(backend, "backendType", "ErrorTrackingBackend"); + setParStr(backend, "backend_type", "ErrorTrackingBackend"); ASSERT_EQ(backend->backend, nullptr); EXPECT_ANY_THROW({ backend->getQuantumBackend(); }); } TEST_F(BackendContainerTest, getBackendConfiguration) { - setParStr(backend, "backendType", "ErrorTrackingBackend"); + setParStr(backend, "backend_type", "ErrorTrackingBackend"); backend->callInitialize(); ASSERT_NE(backend->backend, nullptr); auto *b = backend->getQuantumBackend(); @@ -108,7 +108,7 @@ TEST_F(BackendContainerTest, getBackendConfiguration) { } TEST_F(BackendContainerTest, getCopyOfBackendConfiguration) { - setParStr(backend, "backendType", "ErrorTrackingBackend"); + setParStr(backend, "backend_type", "ErrorTrackingBackend"); backend->callInitialize(); ASSERT_NE(backend->backend, nullptr); auto *b = backend->getQuantumBackend(); diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 1f556358c..e05228fe4 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -135,76 +135,76 @@ TEST_F(StatQubitTest, init) { TEST_F(StatQubitTest, errorTrackingQubitConfigurationOverwrite) { auto *config = new ErrorTrackingConfiguration(); - setParDouble(qubit, "CNOTgate_error_rate", 0.01); - setParDouble(qubit, "CNOTgate_IX_error_ratio", 0.02); - setParDouble(qubit, "CNOTgate_XI_error_ratio", 0.03); - setParDouble(qubit, "CNOTgate_XX_error_ratio", 0.04); - setParDouble(qubit, "CNOTgate_IZ_error_ratio", 0.05); - setParDouble(qubit, "CNOTgate_ZI_error_ratio", 0.06); - setParDouble(qubit, "CNOTgate_ZZ_error_ratio", 0.07); - setParDouble(qubit, "CNOTgate_IY_error_ratio", 0.08); - setParDouble(qubit, "CNOTgate_YI_error_ratio", 0.09); - setParDouble(qubit, "CNOTgate_YY_error_ratio", 0.10); - - setParDouble(qubit, "Hgate_error_rate", 0.11); - setParDouble(qubit, "Hgate_X_error_ratio", 0.12); - setParDouble(qubit, "Hgate_Y_error_ratio", 0.13); - setParDouble(qubit, "Hgate_Z_error_ratio", 0.14); - - setParDouble(qubit, "Xgate_error_rate", 0.15); - setParDouble(qubit, "Xgate_X_error_ratio", 0.16); - setParDouble(qubit, "Xgate_Y_error_ratio", 0.17); - setParDouble(qubit, "Xgate_Z_error_ratio", 0.18); - - setParDouble(qubit, "Zgate_error_rate", 0.19); - setParDouble(qubit, "Zgate_X_error_ratio", 0.20); - setParDouble(qubit, "Zgate_Y_error_ratio", 0.21); - setParDouble(qubit, "Zgate_Z_error_ratio", 0.22); - - setParDouble(qubit, "X_measurement_error_rate", 0.23); - setParDouble(qubit, "Y_measurement_error_rate", 0.24); - setParDouble(qubit, "Z_measurement_error_rate", 0.25); - - setParDouble(qubit, "memory_X_error_rate", 0.26); - setParDouble(qubit, "memory_Y_error_rate", 0.27); - setParDouble(qubit, "memory_Z_error_rate", 0.28); + setParDouble(qubit, "cnot_gate_error_rate", 0.01); + setParDouble(qubit, "cnot_gate_ix_error_ratio", 0.02); + setParDouble(qubit, "cnot_gate_xi_error_ratio", 0.03); + setParDouble(qubit, "cnot_gate_xx_error_ratio", 0.04); + setParDouble(qubit, "cnot_gate_iz_error_ratio", 0.05); + setParDouble(qubit, "cnot_gate_zi_error_ratio", 0.06); + setParDouble(qubit, "cnot_gate_zz_error_ratio", 0.07); + setParDouble(qubit, "cnot_gate_iy_error_ratio", 0.08); + setParDouble(qubit, "cnot_gate_yi_error_ratio", 0.09); + setParDouble(qubit, "cnot_gate_yy_error_ratio", 0.10); + + setParDouble(qubit, "h_gate_error_rate", 0.11); + setParDouble(qubit, "h_gate_x_error_ratio", 0.12); + setParDouble(qubit, "h_gate_y_error_ratio", 0.13); + setParDouble(qubit, "h_gate_z_error_ratio", 0.14); + + setParDouble(qubit, "x_gate_error_rate", 0.15); + setParDouble(qubit, "x_gate_x_error_ratio", 0.16); + setParDouble(qubit, "x_gate_y_error_ratio", 0.17); + setParDouble(qubit, "x_gate_z_error_ratio", 0.18); + + setParDouble(qubit, "z_gate_error_rate", 0.19); + setParDouble(qubit, "z_gate_x_error_ratio", 0.20); + setParDouble(qubit, "z_gate_y_error_ratio", 0.21); + setParDouble(qubit, "z_gate_z_error_ratio", 0.22); + + setParDouble(qubit, "x_measurement_error_rate", 0.23); + setParDouble(qubit, "y_measurement_error_rate", 0.24); + setParDouble(qubit, "z_measurement_error_rate", 0.25); + + setParDouble(qubit, "memory_x_error_rate", 0.26); + setParDouble(qubit, "memory_y_error_rate", 0.27); + setParDouble(qubit, "memory_z_error_rate", 0.28); setParDouble(qubit, "memory_energy_excitation_rate", 0.29); setParDouble(qubit, "memory_energy_relaxation_rate", 0.30); setParDouble(qubit, "memory_completely_mixed_rate", 0.31); - EXPECT_NE(config->cnot_gate_err_rate, qubit->par("CNOTgate_error_rate").doubleValue()); - EXPECT_NE(config->cnot_gate_ix_err_ratio, qubit->par("CNOTgate_IX_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_xi_err_ratio, qubit->par("CNOTgate_XI_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_xx_err_ratio, qubit->par("CNOTgate_XX_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_iz_err_ratio, qubit->par("CNOTgate_IZ_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_zi_err_ratio, qubit->par("CNOTgate_ZI_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_zz_err_ratio, qubit->par("CNOTgate_ZZ_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_iy_err_ratio, qubit->par("CNOTgate_IY_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_yi_err_ratio, qubit->par("CNOTgate_YI_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_yy_err_ratio, qubit->par("CNOTgate_YY_error_ratio").doubleValue()); - - EXPECT_NE(config->h_gate_err_rate, qubit->par("Hgate_error_rate").doubleValue()); - EXPECT_NE(config->h_gate_x_err_ratio, qubit->par("Hgate_X_error_ratio").doubleValue()); - EXPECT_NE(config->h_gate_y_err_ratio, qubit->par("Hgate_Y_error_ratio").doubleValue()); - EXPECT_NE(config->h_gate_z_err_ratio, qubit->par("Hgate_Z_error_ratio").doubleValue()); - - EXPECT_NE(config->x_gate_err_rate, qubit->par("Xgate_error_rate").doubleValue()); - EXPECT_NE(config->x_gate_x_err_ratio, qubit->par("Xgate_X_error_ratio").doubleValue()); - EXPECT_NE(config->x_gate_y_err_ratio, qubit->par("Xgate_Y_error_ratio").doubleValue()); - EXPECT_NE(config->x_gate_z_err_ratio, qubit->par("Xgate_Z_error_ratio").doubleValue()); - - EXPECT_NE(config->z_gate_err_rate, qubit->par("Zgate_error_rate").doubleValue()); - EXPECT_NE(config->z_gate_x_err_ratio, qubit->par("Zgate_X_error_ratio").doubleValue()); - EXPECT_NE(config->z_gate_y_err_ratio, qubit->par("Zgate_Y_error_ratio").doubleValue()); - EXPECT_NE(config->z_gate_z_err_ratio, qubit->par("Zgate_Z_error_ratio").doubleValue()); - - EXPECT_NE(config->measurement_x_err_rate, qubit->par("X_measurement_error_rate").doubleValue()); - EXPECT_NE(config->measurement_y_err_rate, qubit->par("Y_measurement_error_rate").doubleValue()); - EXPECT_NE(config->measurement_z_err_rate, qubit->par("Z_measurement_error_rate").doubleValue()); - - EXPECT_NE(config->memory_x_err_rate, qubit->par("memory_X_error_rate").doubleValue()); - EXPECT_NE(config->memory_y_err_rate, qubit->par("memory_Y_error_rate").doubleValue()); - EXPECT_NE(config->memory_z_err_rate, qubit->par("memory_Z_error_rate").doubleValue()); + EXPECT_NE(config->cnot_gate_err_rate, qubit->par("cnot_gate_error_rate").doubleValue()); + EXPECT_NE(config->cnot_gate_ix_err_ratio, qubit->par("cnot_gate_ix_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_xi_err_ratio, qubit->par("cnot_gate_xI_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_xx_err_ratio, qubit->par("cnot_gate_xx_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_iz_err_ratio, qubit->par("cnot_gate_iz_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_zi_err_ratio, qubit->par("cnot_gate_zi_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_zz_err_ratio, qubit->par("cnot_gate_zz_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_iy_err_ratio, qubit->par("cnot_gate_iy_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_yi_err_ratio, qubit->par("cnot_gate_yi_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_yy_err_ratio, qubit->par("cnot_gate_yy_error_ratio").doubleValue()); + + EXPECT_NE(config->h_gate_err_rate, qubit->par("h_gate_error_rate").doubleValue()); + EXPECT_NE(config->h_gate_x_err_ratio, qubit->par("h_gate_x_error_ratio").doubleValue()); + EXPECT_NE(config->h_gate_y_err_ratio, qubit->par("h_gate_y_error_ratio").doubleValue()); + EXPECT_NE(config->h_gate_z_err_ratio, qubit->par("h_gate_z_error_ratio").doubleValue()); + + EXPECT_NE(config->x_gate_err_rate, qubit->par("x_gate_error_rate").doubleValue()); + EXPECT_NE(config->x_gate_x_err_ratio, qubit->par("x_gate_x_error_ratio").doubleValue()); + EXPECT_NE(config->x_gate_y_err_ratio, qubit->par("x_gate_y_error_ratio").doubleValue()); + EXPECT_NE(config->x_gate_z_err_ratio, qubit->par("x_gate_z_error_ratio").doubleValue()); + + EXPECT_NE(config->z_gate_err_rate, qubit->par("z_gate_error_rate").doubleValue()); + EXPECT_NE(config->z_gate_x_err_ratio, qubit->par("z_gate_x_error_ratio").doubleValue()); + EXPECT_NE(config->z_gate_y_err_ratio, qubit->par("z_gate_y_error_ratio").doubleValue()); + EXPECT_NE(config->z_gate_z_err_ratio, qubit->par("z_gate_z_error_ratio").doubleValue()); + + EXPECT_NE(config->measurement_x_err_rate, qubit->par("x_measurement_error_rate").doubleValue()); + EXPECT_NE(config->measurement_y_err_rate, qubit->par("y_measurement_error_rate").doubleValue()); + EXPECT_NE(config->measurement_z_err_rate, qubit->par("z_measurement_error_rate").doubleValue()); + + EXPECT_NE(config->memory_x_err_rate, qubit->par("memory_x_error_rate").doubleValue()); + EXPECT_NE(config->memory_y_err_rate, qubit->par("memory_y_error_rate").doubleValue()); + EXPECT_NE(config->memory_z_err_rate, qubit->par("memory_z_error_rate").doubleValue()); EXPECT_NE(config->memory_excitation_rate, qubit->par("memory_energy_excitation_rate").doubleValue()); EXPECT_NE(config->memory_relaxation_rate, qubit->par("memory_energy_relaxation_rate").doubleValue()); EXPECT_NE(config->memory_completely_mixed_rate, qubit->par("memory_completely_mixed_rate").doubleValue()); @@ -215,39 +215,39 @@ TEST_F(StatQubitTest, errorTrackingQubitConfigurationOverwrite) { EXPECT_CALL(*backend, getDefaultConfiguration()).WillOnce(Return(ByMove(std::unique_ptr(config)))); auto new_conf = qubit->prepareBackendQubitConfiguration(true); - EXPECT_EQ(config->cnot_gate_err_rate, qubit->par("CNOTgate_error_rate").doubleValue()); - EXPECT_EQ(config->cnot_gate_ix_err_ratio, qubit->par("CNOTgate_IX_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_xi_err_ratio, qubit->par("CNOTgate_XI_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_xx_err_ratio, qubit->par("CNOTgate_XX_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_iz_err_ratio, qubit->par("CNOTgate_IZ_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_zi_err_ratio, qubit->par("CNOTgate_ZI_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_zz_err_ratio, qubit->par("CNOTgate_ZZ_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_iy_err_ratio, qubit->par("CNOTgate_IY_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_yi_err_ratio, qubit->par("CNOTgate_YI_error_ratio").doubleValue()); - EXPECT_EQ(config->cnot_gate_yy_err_ratio, qubit->par("CNOTgate_YY_error_ratio").doubleValue()); - - EXPECT_EQ(config->h_gate_err_rate, qubit->par("Hgate_error_rate").doubleValue()); - EXPECT_EQ(config->h_gate_x_err_ratio, qubit->par("Hgate_X_error_ratio").doubleValue()); - EXPECT_EQ(config->h_gate_y_err_ratio, qubit->par("Hgate_Y_error_ratio").doubleValue()); - EXPECT_EQ(config->h_gate_z_err_ratio, qubit->par("Hgate_Z_error_ratio").doubleValue()); - - EXPECT_EQ(config->x_gate_err_rate, qubit->par("Xgate_error_rate").doubleValue()); - EXPECT_EQ(config->x_gate_x_err_ratio, qubit->par("Xgate_X_error_ratio").doubleValue()); - EXPECT_EQ(config->x_gate_y_err_ratio, qubit->par("Xgate_Y_error_ratio").doubleValue()); - EXPECT_EQ(config->x_gate_z_err_ratio, qubit->par("Xgate_Z_error_ratio").doubleValue()); - - EXPECT_EQ(config->z_gate_err_rate, qubit->par("Zgate_error_rate").doubleValue()); - EXPECT_EQ(config->z_gate_x_err_ratio, qubit->par("Zgate_X_error_ratio").doubleValue()); - EXPECT_EQ(config->z_gate_y_err_ratio, qubit->par("Zgate_Y_error_ratio").doubleValue()); - EXPECT_EQ(config->z_gate_z_err_ratio, qubit->par("Zgate_Z_error_ratio").doubleValue()); - - EXPECT_EQ(config->measurement_x_err_rate, qubit->par("X_measurement_error_rate").doubleValue()); - EXPECT_EQ(config->measurement_y_err_rate, qubit->par("Y_measurement_error_rate").doubleValue()); - EXPECT_EQ(config->measurement_z_err_rate, qubit->par("Z_measurement_error_rate").doubleValue()); - - EXPECT_EQ(config->memory_x_err_rate, qubit->par("memory_X_error_rate").doubleValue()); - EXPECT_EQ(config->memory_y_err_rate, qubit->par("memory_Y_error_rate").doubleValue()); - EXPECT_EQ(config->memory_z_err_rate, qubit->par("memory_Z_error_rate").doubleValue()); + EXPECT_EQ(config->cnot_gate_err_rate, qubit->par("cnot_gate_error_rate").doubleValue()); + EXPECT_EQ(config->cnot_gate_ix_err_ratio, qubit->par("cnot_gate_ix_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_xi_err_ratio, qubit->par("cnot_gate_xi_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_xx_err_ratio, qubit->par("cnot_gate_xx_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_iz_err_ratio, qubit->par("cnot_gate_iz_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_zi_err_ratio, qubit->par("cnot_gate_zi_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_zz_err_ratio, qubit->par("cnot_gate_zz_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_iy_err_ratio, qubit->par("cnot_gate_iy_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_yi_err_ratio, qubit->par("cnot_gate_yi_error_ratio").doubleValue()); + EXPECT_EQ(config->cnot_gate_yy_err_ratio, qubit->par("cnot_gate_yy_error_ratio").doubleValue()); + + EXPECT_EQ(config->h_gate_err_rate, qubit->par("h_gate_error_rate").doubleValue()); + EXPECT_EQ(config->h_gate_x_err_ratio, qubit->par("h_gate_x_error_ratio").doubleValue()); + EXPECT_EQ(config->h_gate_y_err_ratio, qubit->par("h_gate_y_error_ratio").doubleValue()); + EXPECT_EQ(config->h_gate_z_err_ratio, qubit->par("h_gate_z_error_ratio").doubleValue()); + + EXPECT_EQ(config->x_gate_err_rate, qubit->par("x_gate_error_rate").doubleValue()); + EXPECT_EQ(config->x_gate_x_err_ratio, qubit->par("x_gate_x_error_ratio").doubleValue()); + EXPECT_EQ(config->x_gate_y_err_ratio, qubit->par("x_gate_y_error_ratio").doubleValue()); + EXPECT_EQ(config->x_gate_z_err_ratio, qubit->par("x_gate_z_error_ratio").doubleValue()); + + EXPECT_EQ(config->z_gate_err_rate, qubit->par("z_gate_error_rate").doubleValue()); + EXPECT_EQ(config->z_gate_x_err_ratio, qubit->par("z_gate_x_error_ratio").doubleValue()); + EXPECT_EQ(config->z_gate_y_err_ratio, qubit->par("z_gate_y_error_ratio").doubleValue()); + EXPECT_EQ(config->z_gate_z_err_ratio, qubit->par("z_gate_z_error_ratio").doubleValue()); + + EXPECT_EQ(config->measurement_x_err_rate, qubit->par("x_measurement_error_rate").doubleValue()); + EXPECT_EQ(config->measurement_y_err_rate, qubit->par("y_measurement_error_rate").doubleValue()); + EXPECT_EQ(config->measurement_z_err_rate, qubit->par("z_measurement_error_rate").doubleValue()); + + EXPECT_EQ(config->memory_x_err_rate, qubit->par("memory_x_error_rate").doubleValue()); + EXPECT_EQ(config->memory_y_err_rate, qubit->par("memory_y_error_rate").doubleValue()); + EXPECT_EQ(config->memory_z_err_rate, qubit->par("memory_z_error_rate").doubleValue()); EXPECT_EQ(config->memory_excitation_rate, qubit->par("memory_energy_excitation_rate").doubleValue()); EXPECT_EQ(config->memory_relaxation_rate, qubit->par("memory_energy_relaxation_rate").doubleValue()); EXPECT_EQ(config->memory_completely_mixed_rate, qubit->par("memory_completely_mixed_rate").doubleValue()); From 0bec545947a4e1239f3ec3e1756e46464974da37 Mon Sep 17 00:00:00 2001 From: soon Date: Sun, 8 Jan 2023 12:09:05 +0000 Subject: [PATCH 30/43] adapt measurement outcome for runtime --- quisp/backends/interfaces/IQubit.h | 1 + quisp/runtime/types.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/quisp/backends/interfaces/IQubit.h b/quisp/backends/interfaces/IQubit.h index 0d877745a..c39a27f59 100644 --- a/quisp/backends/interfaces/IQubit.h +++ b/quisp/backends/interfaces/IQubit.h @@ -22,6 +22,7 @@ struct MeasurementOutcome { char basis; bool outcome_is_plus; char GOD_clean; + bool operator==(const MeasurementOutcome &outcome) const { return basis == outcome.basis && outcome_is_plus == outcome.outcome_is_plus && GOD_clean == outcome.GOD_clean; } }; class IQubitId; diff --git a/quisp/runtime/types.h b/quisp/runtime/types.h index 8e79ba75b..ab551c394 100644 --- a/quisp/runtime/types.h +++ b/quisp/runtime/types.h @@ -23,7 +23,7 @@ using String = std::string; using IQubitRecord = quisp::modules::qrsa::IQubitRecord; /// @brief measurement outcome for Instructions. -using MeasurementOutcome = quisp::modules::measurement_outcome; +using MeasurementOutcome = quisp::backends::MeasurementOutcome; /// @brief alias for omnetpp's simulation time. using Time = omnetpp::SimTime; From c4b9d5cd01fc7a33454fbd21d2a8e6be58d6dea7 Mon Sep 17 00:00:00 2001 From: soon Date: Sun, 8 Jan 2023 12:10:01 +0000 Subject: [PATCH 31/43] add photonicQubit as namespace for stationary qubit unit test --- quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index e05228fe4..9c338be9e 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -24,6 +24,7 @@ using namespace quisp_test; using namespace Eigen; using namespace omnetpp; using quisp::backends::ErrorTrackingConfiguration; +using quisp::messages::PhotonicQubit; namespace { From 2894c78d47f28d3c2e4259774b1a46d2caab6af7 Mon Sep 17 00:00:00 2001 From: soon Date: Sun, 8 Jan 2023 12:12:03 +0000 Subject: [PATCH 32/43] move typedef Complex and single_qubit_error out from stationary qubit to hardware monitor --- quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h | 7 ------- quisp/modules/QNIC/StationaryQubit/StationaryQubit.h | 1 - quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.cc | 6 +++--- quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h | 9 +++++++++ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h index 1fdaa92a6..162d7cb3e 100644 --- a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h @@ -44,13 +44,6 @@ enum class CliffordOperator : int { } // namespace types namespace modules { -// Matrices of single qubit errors. Used when conducting tomography. -struct single_qubit_error { - Eigen::Matrix2cd X; // double 2*2 matrix - Eigen::Matrix2cd Y; // complex double 2*2 matrix - Eigen::Matrix2cd Z; - Eigen::Matrix2cd I; -}; class IStationaryQubit : public omnetpp::cSimpleModule { public: diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h index 7128b2726..60616a601 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.h @@ -27,7 +27,6 @@ namespace quisp::modules { * \ref https://arxiv.org/abs/1908.10758 */ -typedef std::complex Complex; using quisp::modules::common::IBackendQubit; using quisp::modules::common::IConfiguration; using quisp::modules::common::IQuantumBackend; diff --git a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.cc b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.cc index 83dc905ff..262db1c3c 100644 --- a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.cc +++ b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.cc @@ -43,7 +43,7 @@ void HardwareMonitor::initialize(int stage) { initial.total_count = 0; Pauli.X << 0, 1, 1, 0; - Pauli.Y << 0, Complex(0, -1), Complex(0, 1), 0; + Pauli.Y << 0, std::complex(0, -1), std::complex(0, 1), 0; Pauli.Z << 1, 0, 0, -1; Pauli.I << 1, 0, 0, 1; @@ -371,11 +371,11 @@ void HardwareMonitor::finish() { Bellpair_Z << 1 / sqrt(2), 0, 0, -1 / sqrt(2); Matrix4cd density_matrix_Z = Bellpair_Z * Bellpair_Z.adjoint(); double Zerr_rate = (extended_density_matrix_reconstructed.real() * density_matrix_Z.real()).trace(); - Complex checkZ = Bellpair_Z.adjoint() * extended_density_matrix_reconstructed * Bellpair_Z; + std::complex checkZ = Bellpair_Z.adjoint() * extended_density_matrix_reconstructed * Bellpair_Z; EV << "Zerr = " << Zerr_rate << " or, " << checkZ.real() << "+" << checkZ.imag() << "\n"; Vector4cd Bellpair_Y; - Bellpair_Y << 0, Complex(0, 1 / sqrt(2)), Complex(0, -1 / sqrt(2)), 0; + Bellpair_Y << 0, std::complex(0, 1 / sqrt(2)), std::complex(0, -1 / sqrt(2)), 0; Matrix4cd density_matrix_Y = Bellpair_Y * Bellpair_Y.adjoint(); double Yerr_rate = (extended_density_matrix_reconstructed.real() * density_matrix_Y.real()).trace(); EV << "Yerr = " << Yerr_rate << "\n"; diff --git a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h index 343886cd7..1fb92d528 100644 --- a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h +++ b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace quisp::modules { @@ -33,6 +34,14 @@ class HardwareMonitor : public IHardwareMonitor { utils::ComponentProvider provider; private: + // Matrices of single qubit errors. Used when conducting tomography. + struct single_qubit_error { + Eigen::Matrix2cd X; // double 2*2 matrix + Eigen::Matrix2cd Y; // complex double 2*2 matrix + Eigen::Matrix2cd Z; + Eigen::Matrix2cd I; + }; + int my_address; // number of qnics connected to stand alone HOM or internal hom in the neighbor. From 124dff9fa114ccdf09f1f69ef6442da8abe79f43 Mon Sep 17 00:00:00 2001 From: soon Date: Sun, 8 Jan 2023 12:13:28 +0000 Subject: [PATCH 33/43] add Complex to error tracking backend test header file --- quisp/backends/ErrorTracking/test.h | 1 + 1 file changed, 1 insertion(+) diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index 1b9a9e22d..1b9a191ea 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -18,6 +18,7 @@ using ::quisp::backends::error_tracking::ErrorTrackingConfiguration; using ::quisp::backends::error_tracking::ErrorTrackingQubit; using namespace ::quisp::backends; using namespace ::quisp::backends::abstract; +using Complex = std::complex; class QubitId : public IQubitId { public: From ad2cc614c9ed67a19609081eac645388a8a1e80c Mon Sep 17 00:00:00 2001 From: soon Date: Sun, 8 Jan 2023 12:14:50 +0000 Subject: [PATCH 34/43] remove setFree before getting the backend in stationary qubit --- quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index e884276bd..ee16f9d07 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -53,7 +53,6 @@ void StationaryQubit::initialize() { qnic_type = par("qnic_type"); qnic_index = par("qnic_index"); emission_jittering_standard_deviation = par("emission_jittering_standard_deviation").doubleValue(); - setFree(false); /* e^(t/T1) energy relaxation, e^(t/T2) phase relaxation. Want to use only 1/10 of T1 and T2 in general.*/ From b3510f9606edc5a6ccbb09a3884b975d2aa2a304 Mon Sep 17 00:00:00 2001 From: soon Date: Sun, 8 Jan 2023 12:18:21 +0000 Subject: [PATCH 35/43] normalize forgotten omnet par in stationary qubit test --- quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index 9c338be9e..b5a818154 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -175,7 +175,7 @@ TEST_F(StatQubitTest, errorTrackingQubitConfigurationOverwrite) { EXPECT_NE(config->cnot_gate_err_rate, qubit->par("cnot_gate_error_rate").doubleValue()); EXPECT_NE(config->cnot_gate_ix_err_ratio, qubit->par("cnot_gate_ix_error_ratio").doubleValue()); - EXPECT_NE(config->cnot_gate_xi_err_ratio, qubit->par("cnot_gate_xI_error_ratio").doubleValue()); + EXPECT_NE(config->cnot_gate_xi_err_ratio, qubit->par("cnot_gate_xi_error_ratio").doubleValue()); EXPECT_NE(config->cnot_gate_xx_err_ratio, qubit->par("cnot_gate_xx_error_ratio").doubleValue()); EXPECT_NE(config->cnot_gate_iz_err_ratio, qubit->par("cnot_gate_iz_error_ratio").doubleValue()); EXPECT_NE(config->cnot_gate_zi_err_ratio, qubit->par("cnot_gate_zi_error_ratio").doubleValue()); From d30e62e1955489776876b1e0814cda9954623670 Mon Sep 17 00:00:00 2001 From: soon Date: Thu, 19 Jan 2023 08:06:22 +0000 Subject: [PATCH 36/43] comment out hacked functions in runtime callback --- .../modules/QRSA/RuleEngine/RuntimeCallback.h | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h index 0fbf3c153..d24ade53c 100644 --- a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h +++ b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h @@ -226,37 +226,37 @@ struct RuntimeCallback : public quisp::runtime::Runtime::ICallBack { } void hackSwappingPartners(IQubitRecord *const left_qubit_rec, IQubitRecord *const right_qubit_rec) override { - // HACK: this comes from the original SwappingAction.cc - // manipulate entangled partners to reproduce the situation of entanglement swapping - // this will be not used if we implement more realistic qubit backend - auto *left_qubit = provider.getStationaryQubit(left_qubit_rec); - auto *right_qubit = provider.getStationaryQubit(right_qubit_rec); - auto left_partner_qubit = left_qubit->entangled_partner; - auto right_partner_qubit = right_qubit->entangled_partner; - if (right_partner_qubit == nullptr) throw std::runtime_error("invalid right partner qubit"); - if (left_partner_qubit == nullptr) throw std::runtime_error("invalid left partner qubit"); - right_partner_qubit->setEntangledPartnerInfo(left_partner_qubit); - left_partner_qubit->setEntangledPartnerInfo(right_partner_qubit); - - // HACK: this is also comes from the original SwappingAction.cc - // at the both partner nodes, they need know which qubits are swapped. - // so here these qubit indices are stored and later sendSwappingResults method uses it - // this must be tracked in another way because we can't know these information - // from the actual qubits in real world - right_qubit_index = right_partner_qubit->stationary_qubit_address; - left_qubit_index = left_partner_qubit->stationary_qubit_address; + // // HACK: this comes from the original SwappingAction.cc + // // manipulate entangled partners to reproduce the situation of entanglement swapping + // // this will be not used if we implement more realistic qubit backend + // auto *left_qubit = provider.getStationaryQubit(left_qubit_rec); + // auto *right_qubit = provider.getStationaryQubit(right_qubit_rec); + // auto left_partner_qubit = left_qubit->entangled_partner; + // auto right_partner_qubit = right_qubit->entangled_partner; + // if (right_partner_qubit == nullptr) throw std::runtime_error("invalid right partner qubit"); + // if (left_partner_qubit == nullptr) throw std::runtime_error("invalid left partner qubit"); + // right_partner_qubit->setEntangledPartnerInfo(left_partner_qubit); + // left_partner_qubit->setEntangledPartnerInfo(right_partner_qubit); + + // // HACK: this is also comes from the original SwappingAction.cc + // // at the both partner nodes, they need know which qubits are swapped. + // // so here these qubit indices are stored and later sendSwappingResults method uses it + // // this must be tracked in another way because we can't know these information + // // from the actual qubits in real world + // right_qubit_index = right_partner_qubit->stationary_qubit_address; + // left_qubit_index = left_partner_qubit->stationary_qubit_address; } void hackBreakEntanglement(IQubitRecord *qubit) override { - auto *stat_qubit = rule_engine->provider.getStationaryQubit((qubit)); - // HACK: comes from the original PurifyAction.cc. - // we're freeing the qubit but its entangled_partner will be freed later. - // to pass the validation in RuleEngine::freeFailedQubits_and_AddAsResource for next round, - // break the entanglement manually. - if (stat_qubit->entangled_partner != nullptr && stat_qubit->entangled_partner->entangled_partner != nullptr) { - stat_qubit->entangled_partner->no_density_matrix_nullptr_entangled_partner_ok = true; - stat_qubit->entangled_partner->entangled_partner = nullptr; - } + // auto *stat_qubit = rule_engine->provider.getStationaryQubit((qubit)); + // // HACK: comes from the original PurifyAction.cc. + // // we're freeing the qubit but its entangled_partner will be freed later. + // // to pass the validation in RuleEngine::freeFailedQubits_and_AddAsResource for next round, + // // break the entanglement manually. + // if (stat_qubit->entangled_partner != nullptr && stat_qubit->entangled_partner->entangled_partner != nullptr) { + // stat_qubit->entangled_partner->no_density_matrix_nullptr_entangled_partner_ok = true; + // stat_qubit->entangled_partner->entangled_partner = nullptr; + // } }; std::string getNodeInfo() override { From 914906c2fb528fcfa0fa4ad475ef688bf7b3cc80 Mon Sep 17 00:00:00 2001 From: soon Date: Thu, 19 Jan 2023 12:28:08 +0000 Subject: [PATCH 37/43] add format --- .../QRSA/HardwareMonitor/HardwareMonitor.h | 8 ++++---- .../modules/QRSA/RuleEngine/RuntimeCallback.h | 20 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h index 1fb92d528..71b233f24 100644 --- a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h +++ b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h @@ -36,10 +36,10 @@ class HardwareMonitor : public IHardwareMonitor { private: // Matrices of single qubit errors. Used when conducting tomography. struct single_qubit_error { - Eigen::Matrix2cd X; // double 2*2 matrix - Eigen::Matrix2cd Y; // complex double 2*2 matrix - Eigen::Matrix2cd Z; - Eigen::Matrix2cd I; + Eigen::Matrix2cd X; // double 2*2 matrix + Eigen::Matrix2cd Y; // complex double 2*2 matrix + Eigen::Matrix2cd Z; + Eigen::Matrix2cd I; }; int my_address; diff --git a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h index d24ade53c..e1f0d6959 100644 --- a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h +++ b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h @@ -247,16 +247,16 @@ struct RuntimeCallback : public quisp::runtime::Runtime::ICallBack { // left_qubit_index = left_partner_qubit->stationary_qubit_address; } - void hackBreakEntanglement(IQubitRecord *qubit) override { - // auto *stat_qubit = rule_engine->provider.getStationaryQubit((qubit)); - // // HACK: comes from the original PurifyAction.cc. - // // we're freeing the qubit but its entangled_partner will be freed later. - // // to pass the validation in RuleEngine::freeFailedQubits_and_AddAsResource for next round, - // // break the entanglement manually. - // if (stat_qubit->entangled_partner != nullptr && stat_qubit->entangled_partner->entangled_partner != nullptr) { - // stat_qubit->entangled_partner->no_density_matrix_nullptr_entangled_partner_ok = true; - // stat_qubit->entangled_partner->entangled_partner = nullptr; - // } + void hackBreakEntanglement(IQubitRecord *qubit) override{ + // auto *stat_qubit = rule_engine->provider.getStationaryQubit((qubit)); + // // HACK: comes from the original PurifyAction.cc. + // // we're freeing the qubit but its entangled_partner will be freed later. + // // to pass the validation in RuleEngine::freeFailedQubits_and_AddAsResource for next round, + // // break the entanglement manually. + // if (stat_qubit->entangled_partner != nullptr && stat_qubit->entangled_partner->entangled_partner != nullptr) { + // stat_qubit->entangled_partner->no_density_matrix_nullptr_entangled_partner_ok = true; + // stat_qubit->entangled_partner->entangled_partner = nullptr; + // } }; std::string getNodeInfo() override { From ba536e3c0dda22591bdadb16a9e56f296eb51d12 Mon Sep 17 00:00:00 2001 From: whit3z Date: Fri, 20 Jan 2023 20:49:55 +0900 Subject: [PATCH 38/43] change getQubit to create/get/delete --- quisp/backends/ErrorTracking/Backend.cc | 25 +++++++++++++++---- quisp/backends/ErrorTracking/Backend.h | 4 ++- quisp/backends/ErrorTracking/Backend_test.cc | 22 ++++++++++------ quisp/backends/ErrorTracking/Configuration.h | 1 - quisp/backends/ErrorTracking/Qubit.cc | 1 - .../ErrorTracking/Qubit_gate_error_test.cc | 5 ++-- .../ErrorTracking/Qubit_measurement_test.cc | 5 ++-- .../ErrorTracking/Qubit_memory_error_test.cc | 4 +-- quisp/backends/ErrorTracking/Qubit_test.cc | 5 ++-- quisp/backends/ErrorTracking/test.h | 7 ++++-- quisp/backends/interfaces/IQuantumBackend.h | 4 ++- .../QNIC/StationaryQubit/StationaryQubit.cc | 4 +-- .../QNIC/StationaryQubit/StationaryQubit.ned | 2 -- .../StationaryQubit/StationaryQubit_test.cc | 3 +-- .../mock_backends/MockQuantumBackend.h | 4 ++- 15 files changed, 60 insertions(+), 36 deletions(-) diff --git a/quisp/backends/ErrorTracking/Backend.cc b/quisp/backends/ErrorTracking/Backend.cc index 476bc29d9..c7e38143b 100644 --- a/quisp/backends/ErrorTracking/Backend.cc +++ b/quisp/backends/ErrorTracking/Backend.cc @@ -1,7 +1,4 @@ #include "Backend.h" -#include -#include -#include #include "Qubit.h" #include "backends/ErrorTracking/Configuration.h" #include "backends/interfaces/IConfiguration.h" @@ -24,12 +21,19 @@ ErrorTrackingBackend::~ErrorTrackingBackend() { } } -IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id, std::unique_ptr conf) { +IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id) { auto qubit = qubits.find(id); if (qubit != qubits.cend()) { return qubit->second.get(); } + throw std::runtime_error("ErrorTrackingBackend::getQubit: trying to get qubit with nonexisted Id."); +} + +IQubit* ErrorTrackingBackend::createQubit(const IQubitId* id, std::unique_ptr conf) { + if (qubits.find(id) != qubits.cend()) { + throw std::runtime_error("ErrorTrackingBackend::createQubit: trying to create qubit with already existing Id."); + } auto original_qubit = std::make_unique(id, this); IConfiguration* raw_conf = conf.release(); @@ -46,7 +50,18 @@ IQubit* ErrorTrackingBackend::getQubit(const IQubitId* id, std::unique_ptr ErrorTrackingBackend::getDefaultConfiguration() const { // copy the default backend configuration for each qubit return std::make_unique(*config.get()); diff --git a/quisp/backends/ErrorTracking/Backend.h b/quisp/backends/ErrorTracking/Backend.h index 996e34bd9..97ca4705e 100644 --- a/quisp/backends/ErrorTracking/Backend.h +++ b/quisp/backends/ErrorTracking/Backend.h @@ -29,8 +29,10 @@ class ErrorTrackingBackend : public IQuantumBackend { ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration); ErrorTrackingBackend(std::unique_ptr rng, std::unique_ptr configuration, ICallback* callback); ~ErrorTrackingBackend(); + IQubit* createQubit(const IQubitId* id, std::unique_ptr conf) override; + IQubit* createQubit(const IQubitId* id) override; IQubit* getQubit(const IQubitId* id) override; - IQubit* getQubit(const IQubitId* id, std::unique_ptr configuration) override; + void deleteQubit(const IQubitId* id) override; std::unique_ptr getDefaultConfiguration() const override; const SimTime& getSimTime() override; void setSimTime(SimTime time) override; diff --git a/quisp/backends/ErrorTracking/Backend_test.cc b/quisp/backends/ErrorTracking/Backend_test.cc index 1705d9991..1efd08be4 100644 --- a/quisp/backends/ErrorTracking/Backend_test.cc +++ b/quisp/backends/ErrorTracking/Backend_test.cc @@ -1,8 +1,6 @@ #include "Backend.h" -#include #include #include -#include #include "../interfaces/IRandomNumberGenerator.h" #include "Configuration.h" #include "Qubit.h" @@ -62,10 +60,19 @@ class EtBackendTest : public ::testing::Test { std::unique_ptr backend; }; +TEST_F(EtBackendTest, createQubit) { + auto* id = new QubitId(123); + EXPECT_EQ(backend->qubits.size(), 0); + auto qubit = backend->createQubit(id); + EXPECT_EQ(backend->qubits.size(), 1); + ASSERT_THROW(backend->createQubit(id), std::runtime_error); + EXPECT_EQ(backend->qubits.size(), 1); +} + TEST_F(EtBackendTest, getQubit) { auto* id = new QubitId(123); EXPECT_EQ(backend->qubits.size(), 0); - auto qubit = backend->getQubit(id); + auto qubit = backend->createQubit(id); EXPECT_EQ(backend->qubits.size(), 1); EXPECT_EQ(qubit, backend->getQubit(id)); EXPECT_EQ(backend->qubits.size(), 1); @@ -78,6 +85,7 @@ TEST_F(EtBackendTest, getQubit) { TEST_F(EtBackendTest, getQubitTwice) { auto* id = new QubitId(3); + backend->createQubit(id); auto* qubit1 = backend->getQubit(id); auto* qubit2 = backend->getQubit(id); EXPECT_NE(qubit1, nullptr); @@ -85,13 +93,13 @@ TEST_F(EtBackendTest, getQubitTwice) { EXPECT_EQ(qubit1, qubit2); } -TEST_F(EtBackendTest, getQubitWithInvalidConfiguration) { +TEST_F(EtBackendTest, createQubitWithInvalidConfiguration) { auto conf = new IConfiguration; auto* id = new QubitId(4); - ASSERT_THROW({ backend->getQubit(id, std::unique_ptr(conf)); }, std::runtime_error); + ASSERT_THROW({ backend->createQubit(id, std::unique_ptr(conf)); }, std::runtime_error); } -TEST_F(EtBackendTest, getQubitWithConfiguration) { +TEST_F(EtBackendTest, createQubitWithConfiguration) { auto conf = new ErrorTrackingConfiguration; conf->cnot_gate_err_rate = 0.75; conf->cnot_gate_ix_err_ratio = 0.75 / 9.; @@ -129,7 +137,7 @@ TEST_F(EtBackendTest, getQubitWithConfiguration) { auto* id = new QubitId(123); EXPECT_EQ(backend->qubits.size(), 0); - auto* qubit = backend->getQubit(id, std::move(conf2)); + auto* qubit = backend->createQubit(id, std::move(conf2)); EXPECT_EQ(backend->qubits.size(), 1); EXPECT_EQ(qubit, backend->getQubit(id)); EXPECT_EQ(backend->qubits.size(), 1); diff --git a/quisp/backends/ErrorTracking/Configuration.h b/quisp/backends/ErrorTracking/Configuration.h index 72071e854..cb15aa1ae 100644 --- a/quisp/backends/ErrorTracking/Configuration.h +++ b/quisp/backends/ErrorTracking/Configuration.h @@ -9,7 +9,6 @@ class ErrorTrackingConfiguration : public abstract::IConfiguration { public: ErrorTrackingConfiguration() {} ~ErrorTrackingConfiguration() {} - // ErrorTrackingConfiguration(const ErrorTrackingConfiguration&c) = default; // list up all params double memory_x_err_rate; diff --git a/quisp/backends/ErrorTracking/Qubit.cc b/quisp/backends/ErrorTracking/Qubit.cc index cf2f2a3a2..de23c9f66 100644 --- a/quisp/backends/ErrorTracking/Qubit.cc +++ b/quisp/backends/ErrorTracking/Qubit.cc @@ -1,5 +1,4 @@ #include "Qubit.h" -#include #include "Backend.h" namespace quisp::backends::error_tracking { diff --git a/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc b/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc index 621415f8c..0c317ea01 100644 --- a/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_gate_error_test.cc @@ -1,6 +1,5 @@ #include #include -#include #include #include "test.h" @@ -16,9 +15,9 @@ class EtQubitGateErrorTest : public ::testing::Test { rng = new TestRNG(); rng->double_value = .0; backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); - qubit = dynamic_cast(backend->getQubit(0)); + qubit = dynamic_cast(backend->createQubit(0)); if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); - qubit2 = dynamic_cast(backend->getQubit(1)); + qubit2 = dynamic_cast(backend->createQubit(1)); if (qubit2 == nullptr) throw std::runtime_error("Qubit is nullptr"); backend->setSimTime(SimTime(1, SIMTIME_US)); fillParams(qubit); diff --git a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc index fd2e78200..1c31acca0 100644 --- a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc @@ -1,6 +1,5 @@ #include #include -#include #include #include "test.h" @@ -16,8 +15,8 @@ class EtQubitMeasurementTest : public ::testing::Test { rng->double_value = .0; backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); - qubit = dynamic_cast(backend->getQubit(0)); - another_qubit = dynamic_cast(backend->getQubit(2)); + qubit = dynamic_cast(backend->createQubit(0)); + another_qubit = dynamic_cast(backend->createQubit(2)); backend->setSimTime(SimTime(1, SIMTIME_US)); fillParams(qubit); diff --git a/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc b/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc index 18de1629a..0746af55f 100644 --- a/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_memory_error_test.cc @@ -21,8 +21,8 @@ class ETQubitMemoryErrorTest : public ::testing::Test { rng = new TestRNG(); rng->double_value = .0; backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); - qubit = dynamic_cast(backend->getQubit(0)); - partner_qubit = dynamic_cast(backend->getQubit(1)); + qubit = dynamic_cast(backend->createQubit(0)); + partner_qubit = dynamic_cast(backend->createQubit(1)); if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); backend->setSimTime(SimTime(1, SIMTIME_US)); fillParams(qubit); diff --git a/quisp/backends/ErrorTracking/Qubit_test.cc b/quisp/backends/ErrorTracking/Qubit_test.cc index ccc2f84b4..5b461034d 100644 --- a/quisp/backends/ErrorTracking/Qubit_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_test.cc @@ -2,7 +2,6 @@ #include #include #include -#include #include #include "backends/ErrorTracking/types.h" #include "test.h" @@ -22,8 +21,8 @@ class EtQubitTest : public ::testing::Test { rng = new TestRNG(); rng->double_value = .0; backend = std::make_unique(std::unique_ptr(rng), std::make_unique()); - qubit = dynamic_cast(backend->getQubit(0)); - partner_qubit = dynamic_cast(backend->getQubit(1)); + qubit = dynamic_cast(backend->createQubit(0)); + partner_qubit = dynamic_cast(backend->createQubit(1)); if (qubit == nullptr) throw std::runtime_error("Qubit is nullptr"); backend->setSimTime(SimTime(1, SIMTIME_US)); fillParams(qubit); diff --git a/quisp/backends/ErrorTracking/test.h b/quisp/backends/ErrorTracking/test.h index 1b9a191ea..b740bd466 100644 --- a/quisp/backends/ErrorTracking/test.h +++ b/quisp/backends/ErrorTracking/test.h @@ -81,12 +81,15 @@ class Backend : public ErrorTrackingBackend { public: using ErrorTrackingBackend::qubits; Backend(std::unique_ptr rng, std::unique_ptr config) : ErrorTrackingBackend(std::move(rng), std::move(config)) {} + IQubit* createQubit(int id) { return this->createQubitInternal(new QubitId(id)); } IQubit* getQubit(int id) { return this->getQubitInternal(new QubitId(id)); } IQubit* getQubitInternal(const IQubitId* id) { + return qubits.find(id)->second.get(); + } + IQubit* createQubitInternal(const IQubitId* id) { auto qubit = qubits.find(id); - if (qubit != qubits.cend()) { - return qubit->second.get(); + return nullptr; } auto original_qubit = std::make_unique(id, this); auto* qubit_ptr = original_qubit.get(); diff --git a/quisp/backends/interfaces/IQuantumBackend.h b/quisp/backends/interfaces/IQuantumBackend.h index a69775d7f..419c10fc8 100644 --- a/quisp/backends/interfaces/IQuantumBackend.h +++ b/quisp/backends/interfaces/IQuantumBackend.h @@ -21,8 +21,10 @@ class IQuantumBackend { IQuantumBackend(){}; virtual ~IQuantumBackend(){}; + virtual IQubit* createQubit(const IQubitId* id, std::unique_ptr conf) = 0; + virtual IQubit* createQubit(const IQubitId* id) = 0; virtual IQubit* getQubit(const IQubitId* id) = 0; - virtual IQubit* getQubit(const IQubitId* id, std::unique_ptr configuration) = 0; + virtual void deleteQubit(const IQubitId* id) = 0; virtual std::unique_ptr getDefaultConfiguration() const = 0; virtual const SimTime& getSimTime() = 0; virtual void setSimTime(SimTime time) = 0; diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc index ee16f9d07..51abed301 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc @@ -60,8 +60,8 @@ void StationaryQubit::initialize() { vertex_operator = CliffordOperator::H; backend = provider.getQuantumBackend(); - auto config = prepareBackendQubitConfiguration(par("overwrite_backend_qubit_config").boolValue()); - qubit_ref = backend->getQubit(new QubitId(node_address, qnic_index, qnic_type, stationary_qubit_address), std::move(config)); + auto config = prepareBackendQubitConfiguration(true); + qubit_ref = backend->createQubit(new QubitId(node_address, qnic_index, qnic_type, stationary_qubit_address), std::move(config)); if (qubit_ref == nullptr) throw std::runtime_error("qubit_ref nullptr error"); setFree(false); diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned index 606de5294..b1e2d49d5 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.ned @@ -28,8 +28,6 @@ simple StationaryQubit double emission_x_error_rate = default(0); double emission_y_error_rate = default(0); - bool overwrite_backend_qubit_config = default(false); - // ErrorTracking Backend Qubit Configuration // if overwrite_backend_qubit_config is true, // these params overwrite the default configuration at the backend module. diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc index b5a818154..9d720003c 100644 --- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc +++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit_test.cc @@ -96,7 +96,6 @@ class StatQubitTarget : public StationaryQubit { setParInt(this, "qnic_type", 0); setParInt(this, "qnic_index", 0); setParDouble(this, "emission_jittering_standard_deviation", 0.5); - setParBool(this, "overwrite_backend_qubit_config", false); } TestGate *toLensGate; @@ -128,7 +127,7 @@ TEST_F(StatQubitTest, init) { auto *backend_qubit = new MockBackendQubit(); auto *config = new IConfiguration(); EXPECT_CALL(*backend, getDefaultConfiguration()).WillOnce(Return(ByMove(std::unique_ptr(config)))); - EXPECT_CALL(*backend, getQubit(NotNull(), NotNull())).WillOnce(Return(backend_qubit)); + EXPECT_CALL(*backend, createQubit(NotNull(), NotNull())).WillOnce(Return(backend_qubit)); EXPECT_CALL(*backend_qubit, setFree()).WillOnce(Return()); qubit->callInitialize(); delete backend_qubit; diff --git a/quisp/test_utils/mock_backends/MockQuantumBackend.h b/quisp/test_utils/mock_backends/MockQuantumBackend.h index cc4e8493f..9637afc97 100644 --- a/quisp/test_utils/mock_backends/MockQuantumBackend.h +++ b/quisp/test_utils/mock_backends/MockQuantumBackend.h @@ -13,7 +13,9 @@ using quisp::modules::common::IQubitId; class MockQuantumBackend : public IQuantumBackend { public: MOCK_METHOD(IBackendQubit *, getQubit, (const IQubitId *), (override)); - MOCK_METHOD(IBackendQubit *, getQubit, (const IQubitId *, std::unique_ptr configuration), (override)); + MOCK_METHOD(IBackendQubit *, createQubit, (const IQubitId *, std::unique_ptr configuration), (override)); + MOCK_METHOD(IBackendQubit *, createQubit, (const IQubitId *), (override)); + MOCK_METHOD(void, deleteQubit, (const IQubitId *), (override)); MOCK_METHOD(const SimTime &, getSimTime, (), (override)); MOCK_METHOD(void, setSimTime, (SimTime time), (override)); MOCK_METHOD(std::unique_ptr, getDefaultConfiguration, (), (const, override)); From 50c8ceb9366ea6b8adff834ab8cc265f09566312 Mon Sep 17 00:00:00 2001 From: whit3z Date: Fri, 20 Jan 2023 20:52:03 +0900 Subject: [PATCH 39/43] rename function in measurement test --- .../ErrorTracking/Qubit_measurement_test.cc | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc index 1c31acca0..d4cefbf29 100644 --- a/quisp/backends/ErrorTracking/Qubit_measurement_test.cc +++ b/quisp/backends/ErrorTracking/Qubit_measurement_test.cc @@ -22,7 +22,7 @@ class EtQubitMeasurementTest : public ::testing::Test { fillParams(qubit); fillParams(another_qubit); } - void reset() { + void reinitializeBellpair() { qubit->reset(); another_qubit->reset(); qubit->entangled_partner = another_qubit; @@ -198,7 +198,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { ASSERT_NE(qubit->entangled_partner, nullptr); ASSERT_NE(another_qubit->entangled_partner, nullptr); - reset(); + reinitializeBellpair(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -206,7 +206,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -214,7 +214,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -223,7 +223,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -232,7 +232,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -241,7 +241,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -250,7 +250,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -260,7 +260,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; @@ -273,7 +273,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithoutError) { TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { qubit->measurement_err.x_error_rate = 0.99; - reset(); + reinitializeBellpair(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -281,7 +281,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -289,7 +289,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -298,7 +298,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -307,7 +307,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::MINUS_ONE); @@ -316,7 +316,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureX(), EigenvalueResult::PLUS_ONE); @@ -325,7 +325,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -335,7 +335,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_TRUE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; @@ -347,7 +347,7 @@ TEST_F(EtQubitMeasurementTest, localXMeasurementWithError) { } TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { - reset(); + reinitializeBellpair(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -355,7 +355,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -363,7 +363,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -372,7 +372,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -381,7 +381,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -390,7 +390,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -399,7 +399,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -409,7 +409,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; @@ -423,7 +423,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithoutError) { TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { qubit->measurement_err.z_error_rate = 0.99; - reset(); + reinitializeBellpair(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -431,7 +431,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); EXPECT_FALSE(qubit->has_x_error); @@ -439,7 +439,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -448,7 +448,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -457,7 +457,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.7; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::MINUS_ONE); @@ -466,7 +466,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorX(); rng->double_value = 0.3; EXPECT_EQ(qubit->localMeasureZ(), EigenvalueResult::PLUS_ONE); @@ -475,7 +475,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_FALSE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.7; @@ -485,7 +485,7 @@ TEST_F(EtQubitMeasurementTest, localZMeasurementWithError) { EXPECT_TRUE(another_qubit->has_x_error); EXPECT_FALSE(another_qubit->has_z_error); - reset(); + reinitializeBellpair(); qubit->addErrorZ(); qubit->addErrorX(); rng->double_value = 0.3; From a2a99288eb773ae9788d79be1ce6c3bdd3261376 Mon Sep 17 00:00:00 2001 From: whit3z Date: Fri, 20 Jan 2023 20:58:30 +0900 Subject: [PATCH 40/43] rename struct --- quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h index 71b233f24..b6fed2b83 100644 --- a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h +++ b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.h @@ -35,7 +35,7 @@ class HardwareMonitor : public IHardwareMonitor { private: // Matrices of single qubit errors. Used when conducting tomography. - struct single_qubit_error { + struct SingleQubitError { Eigen::Matrix2cd X; // double 2*2 matrix Eigen::Matrix2cd Y; // complex double 2*2 matrix Eigen::Matrix2cd Z; @@ -68,7 +68,7 @@ class HardwareMonitor : public IHardwareMonitor { cModule *getQnic(int qnic_index, QNIC_type qnic_type); NeighborTable neighbor_table; raw_data *tomography_data; - single_qubit_error Pauli; + SingleQubitError Pauli; TomographyOutcomeTable *temporal_tomography_output; // qnic address -> partner . count_id . outcome LinkCostMap *tomography_runningtime_holder; From 4db986617f96d16076d62255852c24929826e591 Mon Sep 17 00:00:00 2001 From: whit3z Date: Fri, 20 Jan 2023 20:59:52 +0900 Subject: [PATCH 41/43] delete empty function --- .../modules/QRSA/RuleEngine/RuntimeCallback.h | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h index e1f0d6959..ea519a844 100644 --- a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h +++ b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h @@ -226,37 +226,9 @@ struct RuntimeCallback : public quisp::runtime::Runtime::ICallBack { } void hackSwappingPartners(IQubitRecord *const left_qubit_rec, IQubitRecord *const right_qubit_rec) override { - // // HACK: this comes from the original SwappingAction.cc - // // manipulate entangled partners to reproduce the situation of entanglement swapping - // // this will be not used if we implement more realistic qubit backend - // auto *left_qubit = provider.getStationaryQubit(left_qubit_rec); - // auto *right_qubit = provider.getStationaryQubit(right_qubit_rec); - // auto left_partner_qubit = left_qubit->entangled_partner; - // auto right_partner_qubit = right_qubit->entangled_partner; - // if (right_partner_qubit == nullptr) throw std::runtime_error("invalid right partner qubit"); - // if (left_partner_qubit == nullptr) throw std::runtime_error("invalid left partner qubit"); - // right_partner_qubit->setEntangledPartnerInfo(left_partner_qubit); - // left_partner_qubit->setEntangledPartnerInfo(right_partner_qubit); - - // // HACK: this is also comes from the original SwappingAction.cc - // // at the both partner nodes, they need know which qubits are swapped. - // // so here these qubit indices are stored and later sendSwappingResults method uses it - // // this must be tracked in another way because we can't know these information - // // from the actual qubits in real world - // right_qubit_index = right_partner_qubit->stationary_qubit_address; - // left_qubit_index = left_partner_qubit->stationary_qubit_address; } void hackBreakEntanglement(IQubitRecord *qubit) override{ - // auto *stat_qubit = rule_engine->provider.getStationaryQubit((qubit)); - // // HACK: comes from the original PurifyAction.cc. - // // we're freeing the qubit but its entangled_partner will be freed later. - // // to pass the validation in RuleEngine::freeFailedQubits_and_AddAsResource for next round, - // // break the entanglement manually. - // if (stat_qubit->entangled_partner != nullptr && stat_qubit->entangled_partner->entangled_partner != nullptr) { - // stat_qubit->entangled_partner->no_density_matrix_nullptr_entangled_partner_ok = true; - // stat_qubit->entangled_partner->entangled_partner = nullptr; - // } }; std::string getNodeInfo() override { From 3d65c74ddf1b6af42c36dfdd088642226045885f Mon Sep 17 00:00:00 2001 From: whit3z Date: Fri, 20 Jan 2023 21:02:34 +0900 Subject: [PATCH 42/43] clang format --- quisp/backends/ErrorTracking/Backend.cc | 4 +--- quisp/backends/ErrorTracking/test.h | 4 +--- quisp/modules/QRSA/RuleEngine/RuntimeCallback.h | 6 ++---- quisp/rules/Rule.cc | 8 ++++++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/quisp/backends/ErrorTracking/Backend.cc b/quisp/backends/ErrorTracking/Backend.cc index c7e38143b..d6962dfc7 100644 --- a/quisp/backends/ErrorTracking/Backend.cc +++ b/quisp/backends/ErrorTracking/Backend.cc @@ -50,9 +50,7 @@ IQubit* ErrorTrackingBackend::createQubit(const IQubitId* id, std::unique_ptr rng, std::unique_ptr config) : ErrorTrackingBackend(std::move(rng), std::move(config)) {} IQubit* createQubit(int id) { return this->createQubitInternal(new QubitId(id)); } IQubit* getQubit(int id) { return this->getQubitInternal(new QubitId(id)); } - IQubit* getQubitInternal(const IQubitId* id) { - return qubits.find(id)->second.get(); - } + IQubit* getQubitInternal(const IQubitId* id) { return qubits.find(id)->second.get(); } IQubit* createQubitInternal(const IQubitId* id) { auto qubit = qubits.find(id); if (qubit != qubits.cend()) { diff --git a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h index ea519a844..97a6a3763 100644 --- a/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h +++ b/quisp/modules/QRSA/RuleEngine/RuntimeCallback.h @@ -225,11 +225,9 @@ struct RuntimeCallback : public quisp::runtime::Runtime::ICallBack { return qubit->action_index; } - void hackSwappingPartners(IQubitRecord *const left_qubit_rec, IQubitRecord *const right_qubit_rec) override { - } + void hackSwappingPartners(IQubitRecord *const left_qubit_rec, IQubitRecord *const right_qubit_rec) override {} - void hackBreakEntanglement(IQubitRecord *qubit) override{ - }; + void hackBreakEntanglement(IQubitRecord *qubit) override{}; std::string getNodeInfo() override { std::stringstream ss; diff --git a/quisp/rules/Rule.cc b/quisp/rules/Rule.cc index f09803887..dfcb8a6f7 100644 --- a/quisp/rules/Rule.cc +++ b/quisp/rules/Rule.cc @@ -6,14 +6,18 @@ namespace quisp::rules { Rule::Rule(int partner_address, QNIC_type qnic_type, int qnic_id, int shared_tag, bool is_finalized) : shared_tag(shared_tag), is_finalized(is_finalized) { - QnicInterface interface { partner_address, qnic_type, qnic_id }; + QnicInterface interface { + partner_address, qnic_type, qnic_id + }; qnic_interfaces.push_back(interface); }; Rule::Rule(std::vector partner_address, std::vector qnic_type, std::vector qnic_id, int shared_tag, bool is_finalized) : shared_tag(shared_tag), is_finalized(is_finalized) { for (int i = 0; i < partner_address.size(); i++) { - QnicInterface interface { partner_address.at(i), qnic_type.at(i), qnic_id.at(i) }; + QnicInterface interface { + partner_address.at(i), qnic_type.at(i), qnic_id.at(i) + }; qnic_interfaces.push_back(interface); } } From 78f5e344022ba7a9f3bbd0127f1c738f9592769b Mon Sep 17 00:00:00 2001 From: whit3z Date: Fri, 20 Jan 2023 22:09:33 +0900 Subject: [PATCH 43/43] reformat using clang-format-13 --- quisp/rules/Rule.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/quisp/rules/Rule.cc b/quisp/rules/Rule.cc index dfcb8a6f7..f09803887 100644 --- a/quisp/rules/Rule.cc +++ b/quisp/rules/Rule.cc @@ -6,18 +6,14 @@ namespace quisp::rules { Rule::Rule(int partner_address, QNIC_type qnic_type, int qnic_id, int shared_tag, bool is_finalized) : shared_tag(shared_tag), is_finalized(is_finalized) { - QnicInterface interface { - partner_address, qnic_type, qnic_id - }; + QnicInterface interface { partner_address, qnic_type, qnic_id }; qnic_interfaces.push_back(interface); }; Rule::Rule(std::vector partner_address, std::vector qnic_type, std::vector qnic_id, int shared_tag, bool is_finalized) : shared_tag(shared_tag), is_finalized(is_finalized) { for (int i = 0; i < partner_address.size(); i++) { - QnicInterface interface { - partner_address.at(i), qnic_type.at(i), qnic_id.at(i) - }; + QnicInterface interface { partner_address.at(i), qnic_type.at(i), qnic_id.at(i) }; qnic_interfaces.push_back(interface); } }