From e80a08545b55927137a4997b1c66d1d127e6648f Mon Sep 17 00:00:00 2001 From: kvmto Date: Thu, 9 Jul 2026 17:43:28 +0200 Subject: [PATCH 1/8] Support code-declared inlined feedback in memory circuits Codes may declare record->detector feedback corrections as data via two new virtuals (get_inlined_feedback / get_observable_inlined_feedback, empty default = existing behavior); memory_circuit folds the declared records into its detector and observable definitions, so measurement schemes with readout byproducts get deterministic detectors through sample_memory_circuit without a physical correction gate. Co-Authored-By: Claude Fable 5 Signed-off-by: kvmto --- libs/qec/include/cudaq/qec/code.h | 24 +++ libs/qec/lib/code.cpp | 8 + libs/qec/lib/device/memory_circuit.cpp | 117 +++++++++++++-- libs/qec/lib/device/memory_circuit.h | 14 +- libs/qec/lib/experiments.cpp | 49 +++++- libs/qec/python/bindings/py_code.cpp | 61 +++++++- libs/qec/python/tests/test_code.py | 152 +++++++++++++++++++ libs/qec/unittests/CMakeLists.txt | 11 +- libs/qec/unittests/feedback_toy_device.cpp | 56 +++++++ libs/qec/unittests/test_qec.cpp | 164 +++++++++++++++++++++ 10 files changed, 639 insertions(+), 17 deletions(-) create mode 100644 libs/qec/unittests/feedback_toy_device.cpp diff --git a/libs/qec/include/cudaq/qec/code.h b/libs/qec/include/cudaq/qec/code.h index f7b9ea1dc..3a9eefce7 100644 --- a/libs/qec/include/cudaq/qec/code.h +++ b/libs/qec/include/cudaq/qec/code.h @@ -201,6 +201,30 @@ class code : public cudaqx::extension_point { /// @return Tensor representing Lz cudaqx::tensor get_observables_z() const; + /// @brief Get the inlined feedback matrix for detector construction + /// + /// Shape is [numCols x numCols], where numCols = + /// get_num_ancilla_qubits() (one measurement record per ancilla per + /// round, in [Z][X] order). Entry (j, k) = 1 means the cross-round + /// detector comparing record j between consecutive rounds additionally + /// XORs record k of the earlier round, and the final boundary detector + /// for record j additionally XORs record k of the last round. + /// @return Tensor representing the inlined feedback matrix. An empty + /// tensor (the default) means no feedback is applied and detectors are + /// formed from same-record comparisons only. + virtual cudaqx::tensor get_inlined_feedback() const; + + /// @brief Get the inlined feedback matrix for logical observables + /// + /// Shape is [num_observables x numCols], where numCols = + /// get_num_ancilla_qubits() (one measurement record per ancilla per + /// round, in [Z][X] order). Entry (m, k) = 1 means logical observable m + /// additionally XORs record k of every round. + /// @return Tensor representing the observable inlined feedback matrix. + /// An empty tensor (the default) means no feedback is applied to the + /// logical observables. + virtual cudaqx::tensor get_observable_inlined_feedback() const; + /// @brief Get the stabilizer generators /// @return Reference to stabilizers const std::vector &get_stabilizers() const { diff --git a/libs/qec/lib/code.cpp b/libs/qec/lib/code.cpp index 19693b8c5..bb6b720a6 100644 --- a/libs/qec/lib/code.cpp +++ b/libs/qec/lib/code.cpp @@ -61,6 +61,14 @@ cudaqx::tensor code::get_observables_z() const { return to_parity_matrix(m_pauli_observables, stabilizer_type::Z); } +cudaqx::tensor code::get_inlined_feedback() const { + return cudaqx::tensor(); +} + +cudaqx::tensor code::get_observable_inlined_feedback() const { + return cudaqx::tensor(); +} + std::unique_ptr get_code(const std::string &name, const std::vector &stab, const heterogeneous_map options) { diff --git a/libs/qec/lib/device/memory_circuit.cpp b/libs/qec/lib/device/memory_circuit.cpp index b00754a28..b2d8e9ae3 100644 --- a/libs/qec/lib/device/memory_circuit.cpp +++ b/libs/qec/lib/device/memory_circuit.cpp @@ -18,7 +18,9 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const std::vector &z_stabilizers, const std::vector &obs_matrix_flat, std::size_t num_observables, - bool measure_in_x_basis) { + bool measure_in_x_basis, + const std::vector &feedback_flat, + const std::vector &obs_feedback_flat) { // Allocate the data and ancilla qubits cudaq::qvector data(num_data), xstab_anc(numAncx), zstab_anc(numAncz); @@ -39,10 +41,77 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, cudaq::detector(final_syndrome[fixed_offset + i]); } + std::size_t numCols = numAncx + numAncz; + + // Observable inlined feedback accumulation. Nested std::vector is not + // supported in __qpu__ code, so instead of one record vector per + // observable we use a single flat buffer with per-observable prefix + // offsets: observable m's feedback records occupy + // [obs_fb_offset[m], obs_fb_offset[m] + num_rounds * obs_fb_weight[m]), + // laid out round-major within each observable's slice. + std::vector obs_fb_weight(num_observables); + std::vector obs_fb_offset(num_observables); + std::size_t obs_fb_total = 0; + if (obs_feedback_flat.size() > 0) { + for (std::size_t m = 0; m < num_observables; ++m) { + std::size_t weight = 0; + for (std::size_t k = 0; k < numCols; ++k) { + if (obs_feedback_flat[m * numCols + k] != 0) + weight++; + } + obs_fb_weight[m] = weight; + obs_fb_offset[m] = obs_fb_total; + obs_fb_total += num_rounds * weight; + } + } + std::vector obs_fb_records(obs_fb_total); + + // Collect the first-round feedback records for each observable. + if (obs_feedback_flat.size() > 0) { + for (std::size_t m = 0; m < num_observables; ++m) { + std::size_t idx = obs_fb_offset[m]; + for (std::size_t k = 0; k < numCols; ++k) { + if (obs_feedback_flat[m * numCols + k] != 0) + obs_fb_records[idx++] = final_syndrome[k]; + } + } + } + // Generate syndrome data for (std::size_t round = 1; round < num_rounds; ++round) { auto syndrome = stabilizer_round(logical, x_stabilizers, z_stabilizers); - cudaq::detectors(final_syndrome, syndrome); + if (obs_feedback_flat.size() > 0) { + for (std::size_t m = 0; m < num_observables; ++m) { + std::size_t idx = obs_fb_offset[m] + round * obs_fb_weight[m]; + for (std::size_t k = 0; k < numCols; ++k) { + if (obs_feedback_flat[m * numCols + k] != 0) + obs_fb_records[idx++] = syndrome[k]; + } + } + } + if (feedback_flat.size() == 0) { + cudaq::detectors(final_syndrome, syndrome); + } else { + // Cross-round detector for record j: earlier vs current round record, + // augmented with the earlier-round records declared in row j of the + // feedback matrix. + for (std::size_t j = 0; j < numCols; ++j) { + std::size_t fb_weight = 0; + for (std::size_t k = 0; k < numCols; ++k) { + if (feedback_flat[j * numCols + k] != 0) + fb_weight++; + } + std::vector det(2 + fb_weight); + det[0] = final_syndrome[j]; + det[1] = syndrome[j]; + std::size_t det_idx = 2; + for (std::size_t k = 0; k < numCols; ++k) { + if (feedback_flat[j * numCols + k] != 0) + det[det_idx++] = final_syndrome[k]; + } + cudaq::detector(det); + } + } final_syndrome = syndrome; } @@ -58,13 +127,27 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, if (obs_matrix_flat[obs * num_data + q] != 0) support_weight++; } - std::vector obs_support(support_weight); - std::size_t idx = 0; - for (std::size_t q = 0; q < num_data; ++q) { - if (obs_matrix_flat[obs * num_data + q] != 0) - obs_support[idx++] = data_results[q]; + if (obs_feedback_flat.size() == 0) { + std::vector obs_support(support_weight); + std::size_t idx = 0; + for (std::size_t q = 0; q < num_data; ++q) { + if (obs_matrix_flat[obs * num_data + q] != 0) + obs_support[idx++] = data_results[q]; + } + cudaq::logical_observable(obs_support); + } else { + // Feedback records from every round, then the data-qubit support. + std::size_t fb_count = num_rounds * obs_fb_weight[obs]; + std::vector obs_support(fb_count + support_weight); + for (std::size_t i = 0; i < fb_count; ++i) + obs_support[i] = obs_fb_records[obs_fb_offset[obs] + i]; + std::size_t idx = fb_count; + for (std::size_t q = 0; q < num_data; ++q) { + if (obs_matrix_flat[obs * num_data + q] != 0) + obs_support[idx++] = data_results[q]; + } + cudaq::logical_observable(obs_support); } - cudaq::logical_observable(obs_support); } // For each stabilizer, form detectors from data qubit readout connected with @@ -82,7 +165,17 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, } } - std::vector support(support_weight + 1); + // With inlined feedback, the boundary detector for record + // (fixed_offset + x) is extended with the declared last-round records. + std::size_t fb_weight = 0; + if (feedback_flat.size() > 0) { + for (std::size_t k = 0; k < numCols; ++k) { + if (feedback_flat[(fixed_offset + x) * numCols + k] != 0) + fb_weight++; + } + } + + std::vector support(support_weight + 1 + fb_weight); support[0] = final_syndrome[fixed_offset + x]; std::size_t support_idx = 1; for (std::size_t q = 0; q < num_data; ++q) { @@ -90,6 +183,12 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, support[support_idx++] = data_results[q]; } } + if (feedback_flat.size() > 0) { + for (std::size_t k = 0; k < numCols; ++k) { + if (feedback_flat[(fixed_offset + x) * numCols + k] != 0) + support[support_idx++] = final_syndrome[k]; + } + } cudaq::detector(support); } diff --git a/libs/qec/lib/device/memory_circuit.h b/libs/qec/lib/device/memory_circuit.h index 1f0280d9a..a15b25842 100644 --- a/libs/qec/lib/device/memory_circuit.h +++ b/libs/qec/lib/device/memory_circuit.h @@ -29,6 +29,16 @@ namespace cudaq::qec { /// (num_observables × numData entries, values 0/1). /// @param num_observables Number of rows in the observable matrix (k). /// @param measure_in_x_basis Performing X- or Z-memory circuit +/// @param feedback_flat Row-major flattened inlined feedback matrix for +/// detectors. Size is 0 (no feedback; legacy detector structure) or +/// numCols*numCols with numCols = numAncx + numAncz. Entry (j, k) = 1 +/// means the cross-round detector for record j additionally XORs +/// record k of the earlier round, and the final boundary detector for +/// record j additionally XORs record k of the last round. +/// @param obs_feedback_flat Row-major flattened inlined feedback matrix for +/// logical observables. Size is 0 (no feedback) or +/// num_observables*numCols. Entry (m, k) = 1 means logical observable +/// m additionally XORs record k of every round. __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const code::one_qubit_encoding &statePrep, std::size_t numData, std::size_t numAncx, @@ -37,5 +47,7 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const std::vector &z_stabilizers, const std::vector &obs_matrix_flat, std::size_t num_observables, - bool measure_in_x_basis); + bool measure_in_x_basis, + const std::vector &feedback_flat, + const std::vector &obs_feedback_flat); } // namespace cudaq::qec diff --git a/libs/qec/lib/experiments.cpp b/libs/qec/lib/experiments.cpp index 9dbb9d0d1..efb9add83 100644 --- a/libs/qec/lib/experiments.cpp +++ b/libs/qec/lib/experiments.cpp @@ -254,6 +254,29 @@ stabilizer_detector_ranges(std::size_t numRounds, std::size_t numZStabs, return ranges; } +/// @brief Validate and flatten (row-major) an inlined feedback tensor +/// declared by a code. An empty tensor (the identity default) flattens to an +/// empty vector; a non-empty tensor must have shape +/// [expected_rows, expected_cols]. +static std::vector +flatten_feedback_tensor(const cudaqx::tensor &t, + std::size_t expected_rows, std::size_t expected_cols, + const std::string &name) { + if (t.size() == 0) + return {}; + if (t.rank() != 2 || t.shape()[0] != expected_rows || + t.shape()[1] != expected_cols) { + std::string actual; + for (std::size_t d = 0; d < t.rank(); ++d) + actual += (d ? ", " : "") + std::to_string(t.shape()[d]); + throw std::runtime_error(name + " has invalid shape [" + actual + + "] - expected [" + std::to_string(expected_rows) + + ", " + std::to_string(expected_cols) + + "] or an empty tensor."); + } + return std::vector(t.data(), t.data() + t.size()); +} + /// @brief Given a memory circuit setup, sample syndrome and data qubit /// measurements. This is the main driver function that all of the /// sample_memory_circuit overloads invoke. @@ -309,6 +332,12 @@ sample_memory_circuit(const code &code, operation statePrep, const std::size_t numCols = numAncx + numAncz; + auto feedback_flat = flatten_feedback_tensor( + code.get_inlined_feedback(), numCols, numCols, "get_inlined_feedback()"); + auto obs_feedback_flat = + flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, + numCols, "get_observable_inlined_feedback()"); + // Obtain the Measurement-to-Detector (M2D) sparse matrix. // m2d.rows[d] = set of chronological measurement indices whose XOR = detector // d. @@ -316,14 +345,16 @@ sample_memory_circuit(const code &code, operation statePrep, cudaq::M2OSparseMatrix m2o; cudaq::dem_from_kernel(memory_circuit, &noise, /*options=*/{}, m2d, m2o, stabRound, prep, numData, numAncx, numAncz, numRounds, - xVec, zVec, obs_flat, num_obs, !is_z_prep); + xVec, zVec, obs_flat, num_obs, !is_z_prep, + feedback_flat, obs_feedback_flat); // Sample the memory circuit and collect all raw measurements. cudaq::sample_options opts{ .shots = numShots, .noise = noise, .explicit_measurements = true}; - auto result = cudaq::sample(opts, memory_circuit, stabRound, prep, numData, - numAncx, numAncz, numRounds, xVec, zVec, obs_flat, - num_obs, !is_z_prep); + auto result = + cudaq::sample(opts, memory_circuit, stabRound, prep, numData, numAncx, + numAncz, numRounds, xVec, zVec, obs_flat, num_obs, + !is_z_prep, feedback_flat, obs_feedback_flat); // mzTable[shot, meas_idx] = raw 0/1 outcome; shape (numShots, // numMeasPerShot). Measurement layout per shot: numRounds*numCols ancilla, @@ -479,11 +510,19 @@ dem_from_memory_circuit(const code &code, operation statePrep, std::vector obs_flat(logical_obs.data(), logical_obs.data() + logical_obs.size()); + const std::size_t numAnc = numAncx + numAncz; + auto feedback_flat = flatten_feedback_tensor( + code.get_inlined_feedback(), numAnc, numAnc, "get_inlined_feedback()"); + auto obs_feedback_flat = + flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, + numAnc, "get_observable_inlined_feedback()"); + cudaq::dem_options dem_opts; dem_opts.decompose_errors = decompose_errors; auto dem_text = cudaq::dem_from_kernel( memory_circuit, &noise, dem_opts, stabRound, prep, numData, numAncx, - numAncz, numRounds, xVec, zVec, obs_flat, num_obs, !is_z_prep); + numAncz, numRounds, xVec, zVec, obs_flat, num_obs, !is_z_prep, + feedback_flat, obs_feedback_flat); auto dem = cudaq::qec::dem_from_stim_text(dem_text, decompose_errors); const auto numXStabs = code.get_num_x_stabilizers(); diff --git a/libs/qec/python/bindings/py_code.cpp b/libs/qec/python/bindings/py_code.cpp index 8e3c493d7..3c63816b6 100644 --- a/libs/qec/python/bindings/py_code.cpp +++ b/libs/qec/python/bindings/py_code.cpp @@ -29,11 +29,52 @@ using namespace cudaqx; namespace cudaq::qec { +/// @brief Convert the array returned by a Python inlined-feedback getter to +/// an owning cudaqx::tensor. +/// @details The result is coerced to a C-contiguous uint8 numpy array first, +/// so any integer-convertible input (other dtypes, nested lists) is accepted. +/// toTensor only borrows the numpy buffer, so the data is copied into the +/// returned tensor to outlive the temporary Python array. +static cudaqx::tensor feedbackArrayToTensor(nb::object array, + const char *methodName) { + auto np = nb::module_::import_("numpy"); + nb::object coerced = np.attr("ascontiguousarray")(array, np.attr("uint8")); + auto ndarray = nb::cast>(coerced); + if (ndarray.ndim() != 2) + throw std::runtime_error(std::string(methodName) + + " must return a 2-D array."); + auto borrowed = cudaqx::toTensor(ndarray); + cudaqx::tensor owned; + owned.copy(borrowed.data(), borrowed.shape()); + return owned; +} + class PyCode : public qec::code { public: - NB_TRAMPOLINE(qec::code, 6); + NB_TRAMPOLINE(qec::code, 8); protected: + // Trampoline methods for the optional inlined-feedback virtuals: forward to + // a Python override when one exists (converting its numpy result), else + // fall back to the base-class empty default. This is NB_OVERRIDE with a + // custom return conversion, since cudaqx::tensor has no type caster. + cudaqx::tensor get_inlined_feedback() const override { + nb::detail::ticket nb_ticket(nb_trampoline, "get_inlined_feedback", false); + if (nb_ticket.key.is_valid()) + return feedbackArrayToTensor(nb_trampoline.base().attr(nb_ticket.key)(), + "get_inlined_feedback"); + return NBBase::get_inlined_feedback(); + } + + cudaqx::tensor get_observable_inlined_feedback() const override { + nb::detail::ticket nb_ticket(nb_trampoline, + "get_observable_inlined_feedback", false); + if (nb_ticket.key.is_valid()) + return feedbackArrayToTensor(nb_trampoline.base().attr(nb_ticket.key)(), + "get_observable_inlined_feedback"); + return NBBase::get_observable_inlined_feedback(); + } + // Trampoline methods for pure virtual functions std::size_t get_num_data_qubits() const override { NB_OVERRIDE_PURE(get_num_data_qubits); @@ -186,6 +227,24 @@ class PyCodeHandle : public qec::code { return m_py_operation_encodings; } + /// @brief Forward the optional inlined-feedback declarations to the + /// registered Python code when it defines them; otherwise return the + /// base-class empty default (identity detector layout). + cudaqx::tensor get_inlined_feedback() const override { + if (!nb::hasattr(pyCode, "get_inlined_feedback")) + return code::get_inlined_feedback(); + return feedbackArrayToTensor(pyCode.attr("get_inlined_feedback")(), + "get_inlined_feedback"); + } + + cudaqx::tensor get_observable_inlined_feedback() const override { + if (!nb::hasattr(pyCode, "get_observable_inlined_feedback")) + return code::get_observable_inlined_feedback(); + return feedbackArrayToTensor( + pyCode.attr("get_observable_inlined_feedback")(), + "get_observable_inlined_feedback"); + } + protected: // Trampoline methods for pure virtual functions std::size_t get_num_data_qubits() const override { diff --git a/libs/qec/python/tests/test_code.py b/libs/qec/python/tests/test_code.py index 0280d037a..ca8a0f3d1 100644 --- a/libs/qec/python/tests/test_code.py +++ b/libs/qec/python/tests/test_code.py @@ -315,5 +315,157 @@ def test_version(): assert "CUDA-Q QEC" in qec.__version__ +# Kernels for the inlined-feedback toy code: two data qubits with stabilizers +# XX and ZZ, both extracted through a single superdense (Bell-pair) ancilla +# pair (ancx[0] carries the XX record, ancz[0] the ZZ record). The round ends +# with an *uncorrected* record-conditioned byproduct: after the Bell decode, +# ancx[0] sits in the computational basis holding its future measurement +# outcome r_X, so the trailing CX(ancx[0], data[1]) is the unitary equivalent +# of the classically controlled byproduct X^{r_X} on data[1] that a hardware +# frame update would otherwise track. Same gadget and feedback matrices as the +# C++ toy in unittests/feedback_toy_device.cpp / test_qec.cpp (see the full +# derivation there): feedback = [[0, 1], [0, 0]], observable feedback = +# [[0, 1]], with records per round in [Z][X] order. +@cudaq.kernel +def _feedback_toy_prep0(q: patch): + reset(q.data[0]) + reset(q.data[1]) + + +@cudaq.kernel +def _feedback_toy_round(q: patch, x_stabilizers: list[int], + z_stabilizers: list[int]) -> list[cudaq.measure_handle]: + # Bell-prepare the superdense ancilla pair. + h(q.ancx[0]) + x.ctrl(q.ancx[0], q.ancz[0]) + # Couple XX through the X ancilla and ZZ through the Z ancilla. + x.ctrl(q.ancx[0], q.data[0]) + x.ctrl(q.ancx[0], q.data[1]) + x.ctrl(q.data[0], q.ancz[0]) + x.ctrl(q.data[1], q.ancz[0]) + # Decode the Bell pair. + x.ctrl(q.ancx[0], q.ancz[0]) + h(q.ancx[0]) + # Uncorrected record-conditioned byproduct: X^{r_X} on data[1]. + x.ctrl(q.ancx[0], q.data[1]) + # Records in [Z][X] order. + results = mz([*q.ancz, *q.ancx]) + reset(q.ancz[0]) + reset(q.ancx[0]) + return results + + +def test_python_inlined_feedback_toy(): + + @qec.code('py-feedback-toy') + class FeedbackToy: + + def __init__(self): + qec.Code.__init__(self) + self.stabilizers = [ + cudaq.SpinOperator.from_word(w) for w in ["XX", "ZZ"] + ] + self.pauli_observables = [cudaq.SpinOperator.from_word("ZZ")] + self.operation_encodings = { + qec.operation.prep0: _feedback_toy_prep0, + qec.operation.stabilizer_round: _feedback_toy_round + } + + def get_num_data_qubits(self): + return 2 + + def get_num_ancilla_qubits(self): + return 2 + + def get_num_ancilla_x_qubits(self): + return 1 + + def get_num_ancilla_z_qubits(self): + return 1 + + def get_num_x_stabilizers(self): + return 1 + + def get_num_z_stabilizers(self): + return 1 + + def get_inlined_feedback(self): + return np.array([[0, 1], [0, 0]], dtype=np.uint8) + + def get_observable_inlined_feedback(self): + # Exercise the bridge's dtype coercion: int64 instead of uint8. + return np.array([[0, 1]]) + + # Sample on stim, mirroring the C++ unit tests (test_qec links the stim + # target). The toy's X record is genuinely random in round 1, and the + # default (qpp) target does not preserve cross-round mid-circuit + # measurement correlations when sampling Python kernels - independent of + # the inlined-feedback machinery, but this toy (unlike the steane + # example, whose records are all deterministically 0) exposes it. + cudaq.set_target('stim') + + numShots, numRounds = 20, 4 + syndromes, data = qec.sample_memory_circuit(qec.get_code('py-feedback-toy'), + numShots=numShots, + numRounds=numRounds) + + # 1 first-round boundary + 2 * (numRounds - 1) cross-round + 1 final + # boundary detectors, all deterministic (zero) in the noiseless circuit. + assert syndromes.shape == (numShots, 2 * numRounds) + assert not np.any(syndromes) + + # The individual data qubits are randomized by the XX measurement, but + # the ZZ parity must close deterministically every shot. + assert data.shape == (numShots, 2) + assert not np.any(data[:, 0] ^ data[:, 1]) + cudaq.reset_target() + + +def test_python_inlined_feedback_toy_negative_control(): + # The identical toy without the feedback declarations: the uncorrected + # byproduct makes the record-0 detectors non-deterministic and stim must + # reject the circuit. This proves the Python-declared feedback is doing + # the work in the positive test above. + @qec.code('py-feedback-toy-nofb') + class FeedbackToyNoFeedback: + + def __init__(self): + qec.Code.__init__(self) + self.stabilizers = [ + cudaq.SpinOperator.from_word(w) for w in ["XX", "ZZ"] + ] + self.pauli_observables = [cudaq.SpinOperator.from_word("ZZ")] + self.operation_encodings = { + qec.operation.prep0: _feedback_toy_prep0, + qec.operation.stabilizer_round: _feedback_toy_round + } + + def get_num_data_qubits(self): + return 2 + + def get_num_ancilla_qubits(self): + return 2 + + def get_num_ancilla_x_qubits(self): + return 1 + + def get_num_ancilla_z_qubits(self): + return 1 + + def get_num_x_stabilizers(self): + return 1 + + def get_num_z_stabilizers(self): + return 1 + + # stim's determinism analysis (a std::invalid_argument surfaced as + # ValueError) rejects the circuit inside dem_from_kernel, before any + # sampling happens. + with pytest.raises(ValueError, match="non-deterministic detectors"): + qec.sample_memory_circuit(qec.get_code('py-feedback-toy-nofb'), + numShots=20, + numRounds=4) + + if __name__ == "__main__": pytest.main() diff --git a/libs/qec/unittests/CMakeLists.txt b/libs/qec/unittests/CMakeLists.txt index 344d05449..588834825 100644 --- a/libs/qec/unittests/CMakeLists.txt +++ b/libs/qec/unittests/CMakeLists.txt @@ -50,7 +50,16 @@ add_dependencies(CUDAQXQECUnitTests test_decoders_yaml) gtest_discover_tests(test_decoders_yaml) add_executable(test_qec test_qec.cpp) -target_link_libraries(test_qec PRIVATE GTest::gtest_main cudaq-qec cudaq::cudaq-stim-target) +# The inlined-feedback toy code's kernels are nvq++-compiled (like the +# registered codes' *_device.cpp files) so the memory-circuit kernel can +# resolve them through the kernel registry; cudaq::cudaq and nvqir provide +# the runtime symbols that the device object references. +cudaqx_add_device_code(test_qec + SOURCES + feedback_toy_device.cpp +) +target_link_directories(test_qec PRIVATE ${CUDAQ_INSTALL_DIR}/lib) +target_link_libraries(test_qec PRIVATE GTest::gtest_main cudaq-qec cudaq::cudaq nvqir cudaq::cudaq-stim-target) add_dependencies(CUDAQXQECUnitTests test_qec) gtest_discover_tests(test_qec) diff --git a/libs/qec/unittests/feedback_toy_device.cpp b/libs/qec/unittests/feedback_toy_device.cpp new file mode 100644 index 000000000..50b5e2a03 --- /dev/null +++ b/libs/qec/unittests/feedback_toy_device.cpp @@ -0,0 +1,56 @@ +/****************************************************************-*- C++ -*-**** + * Copyright (c) 2026 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +#include "cudaq.h" +#include "cudaq/qec/patch.h" + +// Device kernels for the inlined-feedback toy code used by test_qec.cpp +// (see the QECCodeTester.checkInlinedFeedbackToy* tests). This file is +// nvq++-compiled, like the registered codes' *_device.cpp files, so the +// kernels are visible to the kernel registry that the memory-circuit +// machinery uses to resolve qkernel arguments. + +namespace cudaq::qec::feedback_toy { + +__qpu__ void prep0(patch p) { + for (std::size_t i = 0; i < p.data.size(); i++) + reset(p.data[i]); +} + +// A superdense (Bell-pair) round for a 2-data-qubit code with stabilizers XX +// and ZZ that deliberately ends with an *uncorrected* record-conditioned +// byproduct: after the Bell decode, ancx[0] sits in the computational basis +// holding its future measurement outcome r_X, so the trailing +// CX(ancx[0], data[1]) is the unitary equivalent of the classically +// controlled byproduct X^{r_X} on data[1] that a hardware frame update would +// otherwise track. The stabilizer supports are hardcoded (a single XX and ZZ +// plaquette), so the x/z_stabilizers arguments are intentionally unused. +__qpu__ std::vector +stabilizer_round(patch p, const std::vector &x_stabilizers, + const std::vector &z_stabilizers) { + // Bell-prepare the superdense ancilla pair. + h(p.ancx[0]); + cudaq::x(p.ancx[0], p.ancz[0]); + // Couple XX through the X ancilla and ZZ through the Z ancilla. + cudaq::x(p.ancx[0], p.data[0]); + cudaq::x(p.ancx[0], p.data[1]); + cudaq::x(p.data[0], p.ancz[0]); + cudaq::x(p.data[1], p.ancz[0]); + // Decode the Bell pair. + cudaq::x(p.ancx[0], p.ancz[0]); + h(p.ancx[0]); + // Uncorrected record-conditioned byproduct: X^{r_X} on data[1]. + cudaq::x(p.ancx[0], p.data[1]); + // Records in [Z][X] order. + auto results = mz(p.ancz, p.ancx); + reset(p.ancz[0]); + reset(p.ancx[0]); + return results; +} + +} // namespace cudaq::qec::feedback_toy diff --git a/libs/qec/unittests/test_qec.cpp b/libs/qec/unittests/test_qec.cpp index 47326f084..0358784ed 100644 --- a/libs/qec/unittests/test_qec.cpp +++ b/libs/qec/unittests/test_qec.cpp @@ -2192,3 +2192,167 @@ TEST(PluginLoaderTester, checkCleanupPluginsEdgeCases) { // not do anything. cudaq::qec::cleanup_plugins(cudaq::qec::PluginType::CODE); } + +TEST(QECCodeTester, checkInlinedFeedbackDefaults) { + auto steane = cudaq::qec::get_code("steane"); + auto feedback = steane->get_inlined_feedback(); + EXPECT_EQ(feedback.rank(), 0); + EXPECT_EQ(feedback.size(), 0); + auto obs_feedback = steane->get_observable_inlined_feedback(); + EXPECT_EQ(obs_feedback.rank(), 0); + EXPECT_EQ(obs_feedback.size(), 0); +} + +// Device kernels for the inlined-feedback toy code, nvq++-compiled in +// feedback_toy_device.cpp (host-compiled kernels cannot be resolved through +// the kernel registry that the memory-circuit kernel uses for its qkernel +// arguments). +namespace cudaq::qec::feedback_toy { +__qpu__ void prep0(patch p); +__qpu__ std::vector +stabilizer_round(patch p, const std::vector &x_stabilizers, + const std::vector &z_stabilizers); +} // namespace cudaq::qec::feedback_toy + +namespace { + +// --------------------------------------------------------------------------- +// Toy code for the inlined-feedback tests below. +// +// Two data qubits with stabilizers XX and ZZ and logical observable ZZ. Both +// stabilizers are extracted through a single superdense (Bell-pair) ancilla +// pair: ancx[0] carries the XX record and ancz[0] the ZZ record. The round +// (defined in feedback_toy_device.cpp) deliberately ends with an +// *uncorrected* record-conditioned byproduct: after the Bell decode, ancx[0] +// sits in the computational basis holding its future measurement outcome +// r_X, so the trailing CX(ancx[0], data[1]) is the unitary equivalent of the +// classically-controlled byproduct X^{r_X} on data[1] that a hardware frame +// update would otherwise track. +// +// Derivation of the feedback matrices (records per round in [Z][X] order: +// record 0 = ancz outcome r_Z, record 1 = ancx outcome r_X): +// - r_Z(t) reads the ZZ parity of the data entering round t, i.e. the +// accumulated byproduct parity b_t, with b_1 = 0 and +// b_{t+1} = b_t XOR r_X(t). +// - r_X(t) reads XX: uniformly random in round 1 of a Z-basis memory and +// constant afterwards (the X byproduct commutes with XX). +// - Cross-round detector for record 0 without feedback: +// r_Z(t) XOR r_Z(t+1) = r_X(t) -> non-deterministic (the negative-control +// test relies on stim rejecting exactly this). XOR-ing in the earlier +// round's record 1 fixes it: feedback(0, 1) = 1. +// - Record 1 compares deterministically on its own: feedback row 1 = 0. +// - Final boundary detector for record 0: +// r_Z(T) XOR d0 XOR d1 = b_T XOR b_{T+1} = r_X(T); the same +// feedback(0, 1) entry extends the boundary detector with the last +// round's record 1. +// - The ZZ observable closes as d0 XOR d1 = b_{T+1} = XOR of every round's +// record 1: observable_feedback(0, 1) = 1. +// Note that the byproduct must be heralded by the *other* (X) record: a +// byproduct conditioned on the Z record - which is identically 0 in the +// noiseless circuit - would never fire and could not break determinism. +// Both matrices were validated against stim's determinism analysis for +// 1 through 6 rounds. +// --------------------------------------------------------------------------- + +class feedback_toy_code : public cudaq::qec::code { +protected: + std::size_t get_num_data_qubits() const override { return 2; } + std::size_t get_num_ancilla_qubits() const override { return 2; } + std::size_t get_num_ancilla_x_qubits() const override { return 1; } + std::size_t get_num_ancilla_z_qubits() const override { return 1; } + std::size_t get_num_x_stabilizers() const override { return 1; } + std::size_t get_num_z_stabilizers() const override { return 1; } + + bool declare_feedback; + +public: + explicit feedback_toy_code(bool declare_feedback) + : declare_feedback(declare_feedback) { + operation_encodings.insert(std::make_pair( + cudaq::qec::operation::prep0, cudaq::qec::feedback_toy::prep0)); + operation_encodings.insert( + std::make_pair(cudaq::qec::operation::stabilizer_round, + cudaq::qec::feedback_toy::stabilizer_round)); + m_stabilizers = fromPauliWords({"XX", "ZZ"}); + m_pauli_observables = fromPauliWords({"ZZ"}); + } + + cudaqx::tensor get_inlined_feedback() const override { + if (!declare_feedback) + return code::get_inlined_feedback(); + cudaqx::tensor feedback({2, 2}); + feedback.at({0, 1}) = 1; + return feedback; + } + + cudaqx::tensor get_observable_inlined_feedback() const override { + if (!declare_feedback) + return code::get_observable_inlined_feedback(); + cudaqx::tensor feedback({1, 2}); + feedback.at({0, 1}) = 1; + return feedback; + } +}; + +} // namespace + +TEST(QECCodeTester, checkInlinedFeedbackToyMemoryCircuit) { + feedback_toy_code toy(/*declare_feedback=*/true); + const std::size_t numShots = 20; + const std::size_t numRounds = 4; + auto [syndromes, data] = cudaq::qec::sample_memory_circuit( + toy, cudaq::qec::operation::prep0, numShots, numRounds); + + // 1 first-round boundary + 2 * (numRounds - 1) cross-round + 1 final + // boundary detectors. + ASSERT_EQ(syndromes.rank(), 2); + ASSERT_EQ(syndromes.shape()[0], numShots); + ASSERT_EQ(syndromes.shape()[1], 2 * numRounds); + for (std::size_t shot = 0; shot < numShots; ++shot) + for (std::size_t d = 0; d < syndromes.shape()[1]; ++d) + EXPECT_EQ(syndromes.at({shot, d}), 0) + << "shot " << shot << ", detector " << d; + + // The individual data qubits are randomized by the XX measurement, but the + // ZZ parity must close deterministically every shot. + ASSERT_EQ(data.rank(), 2); + ASSERT_EQ(data.shape()[0], numShots); + ASSERT_EQ(data.shape()[1], 2); + for (std::size_t shot = 0; shot < numShots; ++shot) + EXPECT_EQ(data.at({shot, 0}) ^ data.at({shot, 1}), 0) << "shot " << shot; +} + +TEST(QECCodeTester, checkInlinedFeedbackToyNegativeControl) { + // The identical toy without the feedback declaration: the uncorrected + // byproduct makes the record-0 detectors non-deterministic and stim must + // reject the circuit. This proves the declared feedback is doing the work + // in the positive test above. + feedback_toy_code toy(/*declare_feedback=*/false); + try { + cudaq::qec::sample_memory_circuit( + toy, cudaq::qec::operation::prep0, /*numShots=*/20, /*numRounds=*/4); + FAIL() << "expected sample_memory_circuit to reject the feedback-less toy"; + } catch (const std::exception &e) { + // Fail-for-the-right-reason check: stim's determinism analysis must be + // what rejects the circuit (it flags the record-0 cross-round and final + // boundary detectors). + EXPECT_NE(std::string(e.what()).find("non-deterministic detectors"), + std::string::npos) + << "unexpected failure reason: " << e.what(); + } +} + +TEST(QECCodeTester, checkInlinedFeedbackToyDem) { + // The DEM path threads the same feedback declaration through + // dem_from_kernel; with circuit-level noise it must produce a valid model + // (a noiseless model has no error mechanisms and is rejected downstream). + feedback_toy_code toy(/*declare_feedback=*/true); + cudaq::noise_model noise; + noise.add_all_qubit_channel("x", cudaq::qec::two_qubit_depolarization(0.01), + /*num_controls=*/1); + auto dem = cudaq::qec::dem_from_memory_circuit( + toy, cudaq::qec::operation::prep0, /*numRounds=*/4, noise); + EXPECT_GT(dem.num_detectors(), 0); + EXPECT_GT(dem.num_error_mechanisms(), 0); + EXPECT_EQ(dem.num_observables(), 1); +} From 8bffc7548d4819a3da45f9dde7f58b1050bf30bf Mon Sep 17 00:00:00 2001 From: kvmto Date: Sat, 11 Jul 2026 01:17:28 +0200 Subject: [PATCH 2/8] Extract inlined-feedback composition rule into host-side apply_inlined_feedback The record->detector composition rule now lives in detector_error_model as a CSR layout builder; the memory_circuit kernel is a thin emitter walking the layout. Behavior is bit-identical; all suites pass unchanged. Signed-off-by: kvmto --- .../include/cudaq/qec/detector_error_model.h | 43 +++++++ libs/qec/lib/detector_error_model.cpp | 45 +++++++ libs/qec/lib/device/memory_circuit.cpp | 111 +++++++----------- libs/qec/lib/device/memory_circuit.h | 30 +++-- libs/qec/lib/experiments.cpp | 60 +++------- libs/qec/python/tests/test_code.py | 38 +++--- libs/qec/unittests/test_qec.cpp | 69 ++++++++++- 7 files changed, 254 insertions(+), 142 deletions(-) diff --git a/libs/qec/include/cudaq/qec/detector_error_model.h b/libs/qec/include/cudaq/qec/detector_error_model.h index 64729f3d0..3899dd2f7 100644 --- a/libs/qec/include/cudaq/qec/detector_error_model.h +++ b/libs/qec/include/cudaq/qec/detector_error_model.h @@ -82,6 +82,49 @@ struct detector_error_model { bool remove_zero_syndrome_errors = false); }; +/// @brief Record-to-detector composition layout derived from a code's +/// declared inlined-feedback matrices (CSR-style). +/// +/// Entry range [detector_offsets[j], detector_offsets[j+1]) of +/// detector_indices lists the herald record columns XOR-ed into record j's +/// cross-round detector (records of the earlier round) and into its final +/// boundary detector (records of the last round). Entry range +/// [observable_offsets[m], observable_offsets[m+1]) of observable_indices +/// lists the record columns XOR-ed into logical observable m on every round. +/// Empty offsets vectors mean no feedback is declared for that target +/// (identity detector/observable structure). +struct inlined_feedback_layout { + std::vector detector_indices; + std::vector detector_offsets; + std::vector observable_indices; + std::vector observable_offsets; +}; + +/// @brief Build the record-to-detector composition layout from a code's +/// declared inlined-feedback matrices. +/// +/// @param feedback Detector feedback matrix, shape +/// [num_syndromes_per_round x num_syndromes_per_round] with 0/1 +/// entries, or an empty tensor for none. Entry (j, k) = 1 means the +/// cross-round detector for record j additionally XORs record k of +/// the earlier round, and the final boundary detector for record j +/// additionally XORs record k of the last round. +/// @param obs_feedback Observable feedback matrix, shape +/// [num_observables x num_syndromes_per_round] with 0/1 entries, or +/// an empty tensor for none. Entry (m, k) = 1 means logical +/// observable m additionally XORs record k of every round. +/// @param num_syndromes_per_round Records per round (number of ancilla +/// qubits). +/// @param num_observables Number of logical observables. +/// @return The CSR layout; see inlined_feedback_layout. +/// @throws std::runtime_error if a non-empty tensor's shape does not match +/// the expected dimensions. +inlined_feedback_layout +apply_inlined_feedback(const cudaqx::tensor &feedback, + const cudaqx::tensor &obs_feedback, + std::size_t num_syndromes_per_round, + std::size_t num_observables); + /// Parse the Stim DEM string @p dem_text into detector/observable flip /// matrices and error rates. DEM-native decoders should consume raw DEM text /// instead. By default (@p use_decomp_suggestions = false) the '^' separators diff --git a/libs/qec/lib/detector_error_model.cpp b/libs/qec/lib/detector_error_model.cpp index 79a89b798..aa1c683fc 100644 --- a/libs/qec/lib/detector_error_model.cpp +++ b/libs/qec/lib/detector_error_model.cpp @@ -296,4 +296,49 @@ void detector_error_model::canonicalize_for_rounds( this->observables_flips_matrix, final_column_order); } +/// @brief Convert one 0/1 feedback matrix into a CSR row layout. An empty +/// tensor (the identity default) leaves @p indices and @p offsets empty; a +/// non-empty tensor must have shape [num_rows, num_cols]. +static void feedback_rows_to_csr(const cudaqx::tensor &matrix, + std::size_t num_rows, std::size_t num_cols, + const char *name, + std::vector &indices, + std::vector &offsets) { + if (matrix.rank() == 0 || matrix.size() == 0) + return; + if (matrix.rank() != 2 || matrix.shape()[0] != num_rows || + matrix.shape()[1] != num_cols) { + std::string actual; + for (std::size_t d = 0; d < matrix.rank(); ++d) + actual += (d ? ", " : "") + std::to_string(matrix.shape()[d]); + throw std::runtime_error( + std::string(name) + " has invalid shape [" + actual + "] - expected [" + + std::to_string(num_rows) + ", " + std::to_string(num_cols) + + "] or an empty tensor."); + } + offsets.resize(num_rows + 1); + offsets[0] = 0; + for (std::size_t r = 0; r < num_rows; ++r) { + for (std::size_t c = 0; c < num_cols; ++c) + if (matrix.at({r, c}) != 0) + indices.push_back(c); + offsets[r + 1] = indices.size(); + } +} + +inlined_feedback_layout +apply_inlined_feedback(const cudaqx::tensor &feedback, + const cudaqx::tensor &obs_feedback, + std::size_t num_syndromes_per_round, + std::size_t num_observables) { + inlined_feedback_layout layout; + feedback_rows_to_csr(feedback, num_syndromes_per_round, + num_syndromes_per_round, "inlined feedback", + layout.detector_indices, layout.detector_offsets); + feedback_rows_to_csr(obs_feedback, num_observables, num_syndromes_per_round, + "observable inlined feedback", layout.observable_indices, + layout.observable_offsets); + return layout; +} + } // namespace cudaq::qec diff --git a/libs/qec/lib/device/memory_circuit.cpp b/libs/qec/lib/device/memory_circuit.cpp index b2d8e9ae3..0fa0db3c2 100644 --- a/libs/qec/lib/device/memory_circuit.cpp +++ b/libs/qec/lib/device/memory_circuit.cpp @@ -19,8 +19,10 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const std::vector &obs_matrix_flat, std::size_t num_observables, bool measure_in_x_basis, - const std::vector &feedback_flat, - const std::vector &obs_feedback_flat) { + const std::vector &fb_indices, + const std::vector &fb_offsets, + const std::vector &obs_fb_indices, + const std::vector &obs_fb_offsets) { // Allocate the data and ancilla qubits cudaq::qvector data(num_data), xstab_anc(numAncx), zstab_anc(numAncz); @@ -43,72 +45,51 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, std::size_t numCols = numAncx + numAncz; - // Observable inlined feedback accumulation. Nested std::vector is not - // supported in __qpu__ code, so instead of one record vector per - // observable we use a single flat buffer with per-observable prefix - // offsets: observable m's feedback records occupy - // [obs_fb_offset[m], obs_fb_offset[m] + num_rounds * obs_fb_weight[m]), - // laid out round-major within each observable's slice. - std::vector obs_fb_weight(num_observables); - std::vector obs_fb_offset(num_observables); - std::size_t obs_fb_total = 0; - if (obs_feedback_flat.size() > 0) { - for (std::size_t m = 0; m < num_observables; ++m) { - std::size_t weight = 0; - for (std::size_t k = 0; k < numCols; ++k) { - if (obs_feedback_flat[m * numCols + k] != 0) - weight++; - } - obs_fb_weight[m] = weight; - obs_fb_offset[m] = obs_fb_total; - obs_fb_total += num_rounds * weight; - } - } + // Observable inlined-feedback accumulation. Nested std::vector is not + // supported in __qpu__ code, so observable m's per-round feedback records + // occupy the round-major slice starting at num_rounds * obs_fb_offsets[m] + // of a single flat buffer; the round-r block of observable m starts at + // num_rounds * obs_fb_offsets[m] + r * row_weight(m) with + // row_weight(m) = obs_fb_offsets[m + 1] - obs_fb_offsets[m]. + bool has_obs_fb = obs_fb_offsets.size() > 0; + std::size_t obs_fb_total = + has_obs_fb ? num_rounds * obs_fb_offsets[num_observables] : 0; std::vector obs_fb_records(obs_fb_total); // Collect the first-round feedback records for each observable. - if (obs_feedback_flat.size() > 0) { + if (has_obs_fb) { for (std::size_t m = 0; m < num_observables; ++m) { - std::size_t idx = obs_fb_offset[m]; - for (std::size_t k = 0; k < numCols; ++k) { - if (obs_feedback_flat[m * numCols + k] != 0) - obs_fb_records[idx++] = final_syndrome[k]; - } + std::size_t idx = num_rounds * obs_fb_offsets[m]; + for (std::size_t i = obs_fb_offsets[m]; i < obs_fb_offsets[m + 1]; ++i) + obs_fb_records[idx++] = final_syndrome[obs_fb_indices[i]]; } } // Generate syndrome data for (std::size_t round = 1; round < num_rounds; ++round) { auto syndrome = stabilizer_round(logical, x_stabilizers, z_stabilizers); - if (obs_feedback_flat.size() > 0) { + if (has_obs_fb) { for (std::size_t m = 0; m < num_observables; ++m) { - std::size_t idx = obs_fb_offset[m] + round * obs_fb_weight[m]; - for (std::size_t k = 0; k < numCols; ++k) { - if (obs_feedback_flat[m * numCols + k] != 0) - obs_fb_records[idx++] = syndrome[k]; - } + std::size_t row_weight = obs_fb_offsets[m + 1] - obs_fb_offsets[m]; + std::size_t idx = num_rounds * obs_fb_offsets[m] + round * row_weight; + for (std::size_t i = obs_fb_offsets[m]; i < obs_fb_offsets[m + 1]; ++i) + obs_fb_records[idx++] = syndrome[obs_fb_indices[i]]; } } - if (feedback_flat.size() == 0) { + if (fb_offsets.size() == 0) { cudaq::detectors(final_syndrome, syndrome); } else { // Cross-round detector for record j: earlier vs current round record, - // augmented with the earlier-round records declared in row j of the - // feedback matrix. + // augmented with the earlier-round herald records in row j of the + // feedback layout. for (std::size_t j = 0; j < numCols; ++j) { - std::size_t fb_weight = 0; - for (std::size_t k = 0; k < numCols; ++k) { - if (feedback_flat[j * numCols + k] != 0) - fb_weight++; - } - std::vector det(2 + fb_weight); + std::size_t begin = fb_offsets[j]; + std::size_t end = fb_offsets[j + 1]; + std::vector det(2 + end - begin); det[0] = final_syndrome[j]; det[1] = syndrome[j]; - std::size_t det_idx = 2; - for (std::size_t k = 0; k < numCols; ++k) { - if (feedback_flat[j * numCols + k] != 0) - det[det_idx++] = final_syndrome[k]; - } + for (std::size_t i = begin; i < end; ++i) + det[2 + (i - begin)] = final_syndrome[fb_indices[i]]; cudaq::detector(det); } } @@ -127,7 +108,7 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, if (obs_matrix_flat[obs * num_data + q] != 0) support_weight++; } - if (obs_feedback_flat.size() == 0) { + if (!has_obs_fb) { std::vector obs_support(support_weight); std::size_t idx = 0; for (std::size_t q = 0; q < num_data; ++q) { @@ -137,10 +118,12 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, cudaq::logical_observable(obs_support); } else { // Feedback records from every round, then the data-qubit support. - std::size_t fb_count = num_rounds * obs_fb_weight[obs]; + std::size_t row_weight = obs_fb_offsets[obs + 1] - obs_fb_offsets[obs]; + std::size_t fb_count = num_rounds * row_weight; + std::size_t base = num_rounds * obs_fb_offsets[obs]; std::vector obs_support(fb_count + support_weight); for (std::size_t i = 0; i < fb_count; ++i) - obs_support[i] = obs_fb_records[obs_fb_offset[obs] + i]; + obs_support[i] = obs_fb_records[base + i]; std::size_t idx = fb_count; for (std::size_t q = 0; q < num_data; ++q) { if (obs_matrix_flat[obs * num_data + q] != 0) @@ -166,16 +149,16 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, } // With inlined feedback, the boundary detector for record - // (fixed_offset + x) is extended with the declared last-round records. - std::size_t fb_weight = 0; - if (feedback_flat.size() > 0) { - for (std::size_t k = 0; k < numCols; ++k) { - if (feedback_flat[(fixed_offset + x) * numCols + k] != 0) - fb_weight++; - } + // (fixed_offset + x) is extended with its declared last-round records. + std::size_t fb_begin = 0; + std::size_t fb_end = 0; + if (fb_offsets.size() > 0) { + fb_begin = fb_offsets[fixed_offset + x]; + fb_end = fb_offsets[fixed_offset + x + 1]; } - std::vector support(support_weight + 1 + fb_weight); + std::vector support(support_weight + 1 + + (fb_end - fb_begin)); support[0] = final_syndrome[fixed_offset + x]; std::size_t support_idx = 1; for (std::size_t q = 0; q < num_data; ++q) { @@ -183,12 +166,8 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, support[support_idx++] = data_results[q]; } } - if (feedback_flat.size() > 0) { - for (std::size_t k = 0; k < numCols; ++k) { - if (feedback_flat[(fixed_offset + x) * numCols + k] != 0) - support[support_idx++] = final_syndrome[k]; - } - } + for (std::size_t i = fb_begin; i < fb_end; ++i) + support[support_idx++] = final_syndrome[fb_indices[i]]; cudaq::detector(support); } diff --git a/libs/qec/lib/device/memory_circuit.h b/libs/qec/lib/device/memory_circuit.h index a15b25842..e21ac943b 100644 --- a/libs/qec/lib/device/memory_circuit.h +++ b/libs/qec/lib/device/memory_circuit.h @@ -29,16 +29,20 @@ namespace cudaq::qec { /// (num_observables × numData entries, values 0/1). /// @param num_observables Number of rows in the observable matrix (k). /// @param measure_in_x_basis Performing X- or Z-memory circuit -/// @param feedback_flat Row-major flattened inlined feedback matrix for -/// detectors. Size is 0 (no feedback; legacy detector structure) or -/// numCols*numCols with numCols = numAncx + numAncz. Entry (j, k) = 1 -/// means the cross-round detector for record j additionally XORs -/// record k of the earlier round, and the final boundary detector for -/// record j additionally XORs record k of the last round. -/// @param obs_feedback_flat Row-major flattened inlined feedback matrix for -/// logical observables. Size is 0 (no feedback) or -/// num_observables*numCols. Entry (m, k) = 1 means logical observable -/// m additionally XORs record k of every round. +/// @param fb_indices CSR herald-column indices for the detector inlined +/// feedback layout. `fb_indices[fb_offsets[j] .. fb_offsets[j+1])` +/// lists the herald record columns XORed into record j's cross-round +/// detector (records of the earlier round) and into its final boundary +/// detector (records of the last round). +/// @param fb_offsets CSR row offsets for the detector inlined feedback layout. +/// Size is 0 (no feedback; legacy `cudaq::detectors` structure) or +/// numCols + 1 with numCols = numAncx + numAncz. +/// @param obs_fb_indices CSR record-column indices for the observable inlined +/// feedback layout. `obs_fb_indices[obs_fb_offsets[m] .. +/// obs_fb_offsets[m+1])` lists the record columns XORed into logical +/// observable m on every round. +/// @param obs_fb_offsets CSR row offsets for the observable inlined feedback +/// layout. Size is 0 (no feedback) or num_observables + 1. __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const code::one_qubit_encoding &statePrep, std::size_t numData, std::size_t numAncx, @@ -48,6 +52,8 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const std::vector &obs_matrix_flat, std::size_t num_observables, bool measure_in_x_basis, - const std::vector &feedback_flat, - const std::vector &obs_feedback_flat); + const std::vector &fb_indices, + const std::vector &fb_offsets, + const std::vector &obs_fb_indices, + const std::vector &obs_fb_offsets); } // namespace cudaq::qec diff --git a/libs/qec/lib/experiments.cpp b/libs/qec/lib/experiments.cpp index efb9add83..39a465475 100644 --- a/libs/qec/lib/experiments.cpp +++ b/libs/qec/lib/experiments.cpp @@ -254,29 +254,6 @@ stabilizer_detector_ranges(std::size_t numRounds, std::size_t numZStabs, return ranges; } -/// @brief Validate and flatten (row-major) an inlined feedback tensor -/// declared by a code. An empty tensor (the identity default) flattens to an -/// empty vector; a non-empty tensor must have shape -/// [expected_rows, expected_cols]. -static std::vector -flatten_feedback_tensor(const cudaqx::tensor &t, - std::size_t expected_rows, std::size_t expected_cols, - const std::string &name) { - if (t.size() == 0) - return {}; - if (t.rank() != 2 || t.shape()[0] != expected_rows || - t.shape()[1] != expected_cols) { - std::string actual; - for (std::size_t d = 0; d < t.rank(); ++d) - actual += (d ? ", " : "") + std::to_string(t.shape()[d]); - throw std::runtime_error(name + " has invalid shape [" + actual + - "] - expected [" + std::to_string(expected_rows) + - ", " + std::to_string(expected_cols) + - "] or an empty tensor."); - } - return std::vector(t.data(), t.data() + t.size()); -} - /// @brief Given a memory circuit setup, sample syndrome and data qubit /// measurements. This is the main driver function that all of the /// sample_memory_circuit overloads invoke. @@ -332,29 +309,29 @@ sample_memory_circuit(const code &code, operation statePrep, const std::size_t numCols = numAncx + numAncz; - auto feedback_flat = flatten_feedback_tensor( - code.get_inlined_feedback(), numCols, numCols, "get_inlined_feedback()"); - auto obs_feedback_flat = - flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, - numCols, "get_observable_inlined_feedback()"); + auto fb_layout = apply_inlined_feedback( + code.get_inlined_feedback(), code.get_observable_inlined_feedback(), + numCols, num_obs); // Obtain the Measurement-to-Detector (M2D) sparse matrix. // m2d.rows[d] = set of chronological measurement indices whose XOR = detector // d. cudaq::M2DSparseMatrix m2d; cudaq::M2OSparseMatrix m2o; - cudaq::dem_from_kernel(memory_circuit, &noise, /*options=*/{}, m2d, m2o, - stabRound, prep, numData, numAncx, numAncz, numRounds, - xVec, zVec, obs_flat, num_obs, !is_z_prep, - feedback_flat, obs_feedback_flat); + cudaq::dem_from_kernel( + memory_circuit, &noise, /*options=*/{}, m2d, m2o, stabRound, prep, + numData, numAncx, numAncz, numRounds, xVec, zVec, obs_flat, num_obs, + !is_z_prep, fb_layout.detector_indices, fb_layout.detector_offsets, + fb_layout.observable_indices, fb_layout.observable_offsets); // Sample the memory circuit and collect all raw measurements. cudaq::sample_options opts{ .shots = numShots, .noise = noise, .explicit_measurements = true}; - auto result = - cudaq::sample(opts, memory_circuit, stabRound, prep, numData, numAncx, - numAncz, numRounds, xVec, zVec, obs_flat, num_obs, - !is_z_prep, feedback_flat, obs_feedback_flat); + auto result = cudaq::sample( + opts, memory_circuit, stabRound, prep, numData, numAncx, numAncz, + numRounds, xVec, zVec, obs_flat, num_obs, !is_z_prep, + fb_layout.detector_indices, fb_layout.detector_offsets, + fb_layout.observable_indices, fb_layout.observable_offsets); // mzTable[shot, meas_idx] = raw 0/1 outcome; shape (numShots, // numMeasPerShot). Measurement layout per shot: numRounds*numCols ancilla, @@ -511,18 +488,17 @@ dem_from_memory_circuit(const code &code, operation statePrep, logical_obs.data() + logical_obs.size()); const std::size_t numAnc = numAncx + numAncz; - auto feedback_flat = flatten_feedback_tensor( - code.get_inlined_feedback(), numAnc, numAnc, "get_inlined_feedback()"); - auto obs_feedback_flat = - flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, - numAnc, "get_observable_inlined_feedback()"); + auto fb_layout = apply_inlined_feedback( + code.get_inlined_feedback(), code.get_observable_inlined_feedback(), + numAnc, num_obs); cudaq::dem_options dem_opts; dem_opts.decompose_errors = decompose_errors; auto dem_text = cudaq::dem_from_kernel( memory_circuit, &noise, dem_opts, stabRound, prep, numData, numAncx, numAncz, numRounds, xVec, zVec, obs_flat, num_obs, !is_z_prep, - feedback_flat, obs_feedback_flat); + fb_layout.detector_indices, fb_layout.detector_offsets, + fb_layout.observable_indices, fb_layout.observable_offsets); auto dem = cudaq::qec::dem_from_stim_text(dem_text, decompose_errors); const auto numXStabs = code.get_num_x_stabilizers(); diff --git a/libs/qec/python/tests/test_code.py b/libs/qec/python/tests/test_code.py index ca8a0f3d1..0ba39a425 100644 --- a/libs/qec/python/tests/test_code.py +++ b/libs/qec/python/tests/test_code.py @@ -403,22 +403,28 @@ def get_observable_inlined_feedback(self): # the inlined-feedback machinery, but this toy (unlike the steane # example, whose records are all deterministically 0) exposes it. cudaq.set_target('stim') - - numShots, numRounds = 20, 4 - syndromes, data = qec.sample_memory_circuit(qec.get_code('py-feedback-toy'), - numShots=numShots, - numRounds=numRounds) - - # 1 first-round boundary + 2 * (numRounds - 1) cross-round + 1 final - # boundary detectors, all deterministic (zero) in the noiseless circuit. - assert syndromes.shape == (numShots, 2 * numRounds) - assert not np.any(syndromes) - - # The individual data qubits are randomized by the XX measurement, but - # the ZZ parity must close deterministically every shot. - assert data.shape == (numShots, 2) - assert not np.any(data[:, 0] ^ data[:, 1]) - cudaq.reset_target() + try: + # numRounds >= 2 exercises the final boundary detector (same-round + # herald) distinctly from the cross-round detectors (earlier-round + # herald). + numShots, numRounds = 20, 4 + syndromes, data = qec.sample_memory_circuit( + qec.get_code('py-feedback-toy'), + numShots=numShots, + numRounds=numRounds) + + # 1 first-round boundary + 2 * (numRounds - 1) cross-round + 1 final + # boundary detectors, all deterministic (zero) in the noiseless + # circuit. + assert syndromes.shape == (numShots, 2 * numRounds) + assert not np.any(syndromes) + + # The individual data qubits are randomized by the XX measurement, + # but the ZZ parity must close deterministically every shot. + assert data.shape == (numShots, 2) + assert not np.any(data[:, 0] ^ data[:, 1]) + finally: + cudaq.reset_target() def test_python_inlined_feedback_toy_negative_control(): diff --git a/libs/qec/unittests/test_qec.cpp b/libs/qec/unittests/test_qec.cpp index 0358784ed..429f960b3 100644 --- a/libs/qec/unittests/test_qec.cpp +++ b/libs/qec/unittests/test_qec.cpp @@ -2268,8 +2268,8 @@ class feedback_toy_code : public cudaq::qec::code { public: explicit feedback_toy_code(bool declare_feedback) : declare_feedback(declare_feedback) { - operation_encodings.insert(std::make_pair( - cudaq::qec::operation::prep0, cudaq::qec::feedback_toy::prep0)); + operation_encodings.insert(std::make_pair(cudaq::qec::operation::prep0, + cudaq::qec::feedback_toy::prep0)); operation_encodings.insert( std::make_pair(cudaq::qec::operation::stabilizer_round, cudaq::qec::feedback_toy::stabilizer_round)); @@ -2329,8 +2329,8 @@ TEST(QECCodeTester, checkInlinedFeedbackToyNegativeControl) { // in the positive test above. feedback_toy_code toy(/*declare_feedback=*/false); try { - cudaq::qec::sample_memory_circuit( - toy, cudaq::qec::operation::prep0, /*numShots=*/20, /*numRounds=*/4); + cudaq::qec::sample_memory_circuit(toy, cudaq::qec::operation::prep0, + /*numShots=*/20, /*numRounds=*/4); FAIL() << "expected sample_memory_circuit to reject the feedback-less toy"; } catch (const std::exception &e) { // Fail-for-the-right-reason check: stim's determinism analysis must be @@ -2347,12 +2347,69 @@ TEST(QECCodeTester, checkInlinedFeedbackToyDem) { // dem_from_kernel; with circuit-level noise it must produce a valid model // (a noiseless model has no error mechanisms and is rejected downstream). feedback_toy_code toy(/*declare_feedback=*/true); + const std::size_t numRounds = 4; cudaq::noise_model noise; noise.add_all_qubit_channel("x", cudaq::qec::two_qubit_depolarization(0.01), /*num_controls=*/1); auto dem = cudaq::qec::dem_from_memory_circuit( - toy, cudaq::qec::operation::prep0, /*numRounds=*/4, noise); - EXPECT_GT(dem.num_detectors(), 0); + toy, cudaq::qec::operation::prep0, numRounds, noise); + // 1 first-round boundary + 2 * (numRounds - 1) cross-round + 1 final + // boundary detectors. + EXPECT_EQ(dem.num_detectors(), 2 * numRounds); EXPECT_GT(dem.num_error_mechanisms(), 0); EXPECT_EQ(dem.num_observables(), 1); } + +TEST(InlinedFeedbackLayout, EmptyTensorsGiveEmptyLayout) { + cudaqx::tensor empty; + auto layout = cudaq::qec::apply_inlined_feedback(empty, empty, 2, 1); + EXPECT_TRUE(layout.detector_indices.empty()); + EXPECT_TRUE(layout.detector_offsets.empty()); + EXPECT_TRUE(layout.observable_indices.empty()); + EXPECT_TRUE(layout.observable_offsets.empty()); +} + +TEST(InlinedFeedbackLayout, ToyMatricesCsr) { + // fb = [[0,1],[0,0]]: record 0 heralded by record 1; row 1 empty. + cudaqx::tensor fb({2, 2}); + fb.at({0, 1}) = 1; + // obs_fb = [[0,1]]: observable 0 XORs record 1 every round. + cudaqx::tensor obs_fb({1, 2}); + obs_fb.at({0, 1}) = 1; + auto layout = cudaq::qec::apply_inlined_feedback(fb, obs_fb, 2, 1); + EXPECT_EQ(layout.detector_indices, (std::vector{1})); + EXPECT_EQ(layout.detector_offsets, (std::vector{0, 1, 1})); + EXPECT_EQ(layout.observable_indices, (std::vector{1})); + EXPECT_EQ(layout.observable_offsets, (std::vector{0, 1})); +} + +TEST(InlinedFeedbackLayout, MultiRowWeights) { + // 3x3 with row weights 2, 0, 1. + cudaqx::tensor fb({3, 3}); + fb.at({0, 0}) = 1; + fb.at({0, 2}) = 1; + fb.at({2, 1}) = 1; + cudaqx::tensor empty; + auto layout = cudaq::qec::apply_inlined_feedback(fb, empty, 3, 0); + EXPECT_EQ(layout.detector_indices, (std::vector{0, 2, 1})); + EXPECT_EQ(layout.detector_offsets, (std::vector{0, 2, 2, 3})); + EXPECT_TRUE(layout.observable_offsets.empty()); +} + +TEST(InlinedFeedbackLayout, AllZeroMatrixGivesZeroWeightRows) { + cudaqx::tensor fb({2, 2}); + cudaqx::tensor empty; + auto layout = cudaq::qec::apply_inlined_feedback(fb, empty, 2, 0); + EXPECT_TRUE(layout.detector_indices.empty()); + EXPECT_EQ(layout.detector_offsets, (std::vector{0, 0, 0})); +} + +TEST(InlinedFeedbackLayout, ThrowsOnWrongShape) { + cudaqx::tensor bad({2, 3}); // expected [2 x 2] + cudaqx::tensor empty; + EXPECT_THROW(cudaq::qec::apply_inlined_feedback(bad, empty, 2, 0), + std::runtime_error); + cudaqx::tensor bad_obs({2, 2}); // expected [1 x 2] + EXPECT_THROW(cudaq::qec::apply_inlined_feedback(empty, bad_obs, 2, 1), + std::runtime_error); +} From 8dbe2daa183e7efb99650e7533c5f96ea11545c0 Mon Sep 17 00:00:00 2001 From: kvmto Date: Sat, 11 Jul 2026 02:20:43 +0200 Subject: [PATCH 3/8] Restore data-shaped memory_circuit API; extract feedback logic into named device helpers The kernel keeps its flat-matrix signature; all record-composition logic lives in reusable __qpu__ functions in device/inlined_feedback.h. The host CSR layout builder (build_inlined_feedback_layout) is retained for record-stream consumers and pinned to the kernel by an M2D conformance test Signed-off-by: kvmto --- .../include/cudaq/qec/detector_error_model.h | 8 +- libs/qec/lib/detector_error_model.cpp | 8 +- libs/qec/lib/device/inlined_feedback.h | 161 ++++++++++++++++++ libs/qec/lib/device/memory_circuit.cpp | 143 ++++------------ libs/qec/lib/device/memory_circuit.h | 30 ++-- libs/qec/lib/experiments.cpp | 60 +++++-- libs/qec/unittests/test_qec.cpp | 131 +++++++++++++- 7 files changed, 385 insertions(+), 156 deletions(-) create mode 100644 libs/qec/lib/device/inlined_feedback.h diff --git a/libs/qec/include/cudaq/qec/detector_error_model.h b/libs/qec/include/cudaq/qec/detector_error_model.h index 3899dd2f7..88b053303 100644 --- a/libs/qec/include/cudaq/qec/detector_error_model.h +++ b/libs/qec/include/cudaq/qec/detector_error_model.h @@ -120,10 +120,10 @@ struct inlined_feedback_layout { /// @throws std::runtime_error if a non-empty tensor's shape does not match /// the expected dimensions. inlined_feedback_layout -apply_inlined_feedback(const cudaqx::tensor &feedback, - const cudaqx::tensor &obs_feedback, - std::size_t num_syndromes_per_round, - std::size_t num_observables); +build_inlined_feedback_layout(const cudaqx::tensor &feedback, + const cudaqx::tensor &obs_feedback, + std::size_t num_syndromes_per_round, + std::size_t num_observables); /// Parse the Stim DEM string @p dem_text into detector/observable flip /// matrices and error rates. DEM-native decoders should consume raw DEM text diff --git a/libs/qec/lib/detector_error_model.cpp b/libs/qec/lib/detector_error_model.cpp index aa1c683fc..338f455c3 100644 --- a/libs/qec/lib/detector_error_model.cpp +++ b/libs/qec/lib/detector_error_model.cpp @@ -327,10 +327,10 @@ static void feedback_rows_to_csr(const cudaqx::tensor &matrix, } inlined_feedback_layout -apply_inlined_feedback(const cudaqx::tensor &feedback, - const cudaqx::tensor &obs_feedback, - std::size_t num_syndromes_per_round, - std::size_t num_observables) { +build_inlined_feedback_layout(const cudaqx::tensor &feedback, + const cudaqx::tensor &obs_feedback, + std::size_t num_syndromes_per_round, + std::size_t num_observables) { inlined_feedback_layout layout; feedback_rows_to_csr(feedback, num_syndromes_per_round, num_syndromes_per_round, "inlined feedback", diff --git a/libs/qec/lib/device/inlined_feedback.h b/libs/qec/lib/device/inlined_feedback.h new file mode 100644 index 000000000..9884ba455 --- /dev/null +++ b/libs/qec/lib/device/inlined_feedback.h @@ -0,0 +1,161 @@ +/****************************************************************-*- C++ -*-**** + * Copyright (c) 2024 - 2025 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +#pragma once + +#include "cudaq.h" + +namespace cudaq::qec { + +/// @brief Number of nonzero entries in row @p row of a row-major 0/1 matrix +/// that has @p num_cols columns (i.e. the weight of one feedback/observable/ +/// stabilizer row). +inline __qpu__ std::size_t +row_support_weight(const std::vector &matrix_flat, std::size_t row, + std::size_t num_cols) { + std::size_t weight = 0; + for (std::size_t k = 0; k < num_cols; ++k) + if (matrix_flat[row * num_cols + k] != 0) + weight++; + return weight; +} + +/// @brief Records for the cross-round detector of syndrome record @p j: the +/// earlier-vs-current comparison `{prev[j], curr[j]}` followed by the +/// earlier-round herald records `prev[k]` for each column k (ascending) with +/// `feedback_flat(j, k) != 0`. +inline __qpu__ std::vector cross_round_detector_records( + const std::vector &prev, + const std::vector &curr, std::size_t j, + const std::vector &feedback_flat, std::size_t num_cols) { + std::size_t weight = row_support_weight(feedback_flat, j, num_cols); + std::vector det(2 + weight); + det[0] = prev[j]; + det[1] = curr[j]; + std::size_t idx = 2; + for (std::size_t k = 0; k < num_cols; ++k) + if (feedback_flat[j * num_cols + k] != 0) + det[idx++] = prev[k]; + return det; +} + +/// @brief Records for the boundary detector of syndrome record @p record_row: +/// `{last_syndrome[record_row]}`, then the data-qubit readouts +/// `data_results[q]` for each data qubit q (ascending) in the stabilizer +/// support `stabilizers[row_base + q]`, then the last-round herald records +/// `last_syndrome[k]` for each column k (ascending) with +/// `feedback_flat(record_row, k) != 0`. When @p feedback_flat is empty the +/// herald part contributes nothing, so one helper serves both the +/// feedback and legacy branches. +inline __qpu__ std::vector boundary_detector_records( + const std::vector &last_syndrome, + std::size_t record_row, + const std::vector &data_results, + const std::vector &stabilizers, std::size_t row_base, + std::size_t num_data, const std::vector &feedback_flat, + std::size_t num_cols) { + std::size_t support_weight = 0; + for (std::size_t q = 0; q < num_data; ++q) + if (stabilizers[row_base + q] != 0) + support_weight++; + std::size_t fb_weight = + feedback_flat.size() > 0 + ? row_support_weight(feedback_flat, record_row, num_cols) + : 0; + std::vector support(1 + support_weight + fb_weight); + support[0] = last_syndrome[record_row]; + std::size_t idx = 1; + for (std::size_t q = 0; q < num_data; ++q) + if (stabilizers[row_base + q] != 0) + support[idx++] = data_results[q]; + if (feedback_flat.size() > 0) + for (std::size_t k = 0; k < num_cols; ++k) + if (feedback_flat[record_row * num_cols + k] != 0) + support[idx++] = last_syndrome[k]; + return support; +} + +/// @brief Round-major slice offsets into the observable-feedback buffer. Entry +/// m is the start index of observable m's slice; each observable occupies +/// `num_rounds * (weight of obs_feedback_flat row m)` records. The returned +/// vector has `num_observables + 1` entries; the last entry is the total +/// buffer size. Returns an empty vector when @p obs_feedback_flat is empty +/// (no observable feedback declared). +inline __qpu__ std::vector +observable_feedback_offsets(const std::vector &obs_feedback_flat, + std::size_t num_observables, std::size_t num_cols, + std::size_t num_rounds) { + // Sized (not default) construction: the __qpu__ dialect forbids the default + // std::vector constructor. An empty obs_feedback_flat yields a size-0 vector. + std::size_t num_offsets = + obs_feedback_flat.size() > 0 ? num_observables + 1 : 0; + std::vector offsets(num_offsets); + if (obs_feedback_flat.size() == 0) + return offsets; + std::size_t total = 0; + for (std::size_t m = 0; m < num_observables; ++m) { + offsets[m] = total; + total += num_rounds * row_support_weight(obs_feedback_flat, m, num_cols); + } + offsets[num_observables] = total; + return offsets; +} + +/// @brief Write the records that observable feedback collects during @p round +/// into the round-major @p obs_fb_records buffer. For each observable m, the +/// round-r block starts at `offsets[m] + round * (weight of obs_feedback_flat +/// row m)` and holds `syndrome[k]` for each column k (ascending) with +/// `obs_feedback_flat(m, k) != 0`. Call with round 0 for the first round's +/// syndrome and with the running round index for each subsequent round. +inline __qpu__ void collect_observable_feedback_round( + std::vector &obs_fb_records, + const std::vector &offsets, + const std::vector &syndrome, std::size_t round, + const std::vector &obs_feedback_flat, + std::size_t num_observables, std::size_t num_cols) { + for (std::size_t m = 0; m < num_observables; ++m) { + std::size_t weight = row_support_weight(obs_feedback_flat, m, num_cols); + std::size_t idx = offsets[m] + round * weight; + for (std::size_t k = 0; k < num_cols; ++k) + if (obs_feedback_flat[m * num_cols + k] != 0) + obs_fb_records[idx++] = syndrome[k]; + } +} + +/// @brief Support records for logical observable @p obs: the feedback records +/// collected in @p obs_fb_records (round-major, occupying +/// `[offsets[obs], offsets[obs + 1])`), followed by the data-qubit readouts +/// `data_results[q]` for each data qubit q (ascending) with +/// `obs_matrix_flat(obs, q) != 0`. When @p offsets is empty (no observable +/// feedback declared) the feedback prefix is empty and only the data support +/// is returned. +inline __qpu__ std::vector observable_support_records( + std::size_t obs, const std::vector &obs_matrix_flat, + std::size_t num_data, + const std::vector &data_results, + const std::vector &obs_fb_records, + const std::vector &offsets) { + std::size_t support_weight = + row_support_weight(obs_matrix_flat, obs, num_data); + std::size_t fb_count = 0; + std::size_t base = 0; + if (offsets.size() > 0) { + base = offsets[obs]; + fb_count = offsets[obs + 1] - offsets[obs]; + } + std::vector obs_support(fb_count + support_weight); + for (std::size_t i = 0; i < fb_count; ++i) + obs_support[i] = obs_fb_records[base + i]; + std::size_t idx = fb_count; + for (std::size_t q = 0; q < num_data; ++q) + if (obs_matrix_flat[obs * num_data + q] != 0) + obs_support[idx++] = data_results[q]; + return obs_support; +} + +} // namespace cudaq::qec diff --git a/libs/qec/lib/device/memory_circuit.cpp b/libs/qec/lib/device/memory_circuit.cpp index 0fa0db3c2..ad1a88117 100644 --- a/libs/qec/lib/device/memory_circuit.cpp +++ b/libs/qec/lib/device/memory_circuit.cpp @@ -6,7 +6,7 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ #include "memory_circuit.h" -#include +#include "inlined_feedback.h" namespace cudaq::qec { @@ -19,10 +19,8 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const std::vector &obs_matrix_flat, std::size_t num_observables, bool measure_in_x_basis, - const std::vector &fb_indices, - const std::vector &fb_offsets, - const std::vector &obs_fb_indices, - const std::vector &obs_fb_offsets) { + const std::vector &feedback_flat, + const std::vector &obs_feedback_flat) { // Allocate the data and ancilla qubits cudaq::qvector data(num_data), xstab_anc(numAncx), zstab_anc(numAncz); @@ -45,53 +43,39 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, std::size_t numCols = numAncx + numAncz; - // Observable inlined-feedback accumulation. Nested std::vector is not - // supported in __qpu__ code, so observable m's per-round feedback records - // occupy the round-major slice starting at num_rounds * obs_fb_offsets[m] - // of a single flat buffer; the round-r block of observable m starts at - // num_rounds * obs_fb_offsets[m] + r * row_weight(m) with - // row_weight(m) = obs_fb_offsets[m + 1] - obs_fb_offsets[m]. - bool has_obs_fb = obs_fb_offsets.size() > 0; + // Observable inlined feedback accumulation. Nested std::vector is not + // supported in __qpu__ code, so instead of one record vector per observable + // we use a single flat buffer with per-observable round-major slices; see + // observable_feedback_offsets / collect_observable_feedback_round in + // inlined_feedback.h. + std::vector obs_fb_offsets = observable_feedback_offsets( + obs_feedback_flat, num_observables, numCols, num_rounds); std::size_t obs_fb_total = - has_obs_fb ? num_rounds * obs_fb_offsets[num_observables] : 0; + obs_feedback_flat.size() > 0 ? obs_fb_offsets[num_observables] : 0; std::vector obs_fb_records(obs_fb_total); // Collect the first-round feedback records for each observable. - if (has_obs_fb) { - for (std::size_t m = 0; m < num_observables; ++m) { - std::size_t idx = num_rounds * obs_fb_offsets[m]; - for (std::size_t i = obs_fb_offsets[m]; i < obs_fb_offsets[m + 1]; ++i) - obs_fb_records[idx++] = final_syndrome[obs_fb_indices[i]]; - } - } + if (obs_feedback_flat.size() > 0) + collect_observable_feedback_round(obs_fb_records, obs_fb_offsets, + final_syndrome, 0, obs_feedback_flat, + num_observables, numCols); // Generate syndrome data for (std::size_t round = 1; round < num_rounds; ++round) { auto syndrome = stabilizer_round(logical, x_stabilizers, z_stabilizers); - if (has_obs_fb) { - for (std::size_t m = 0; m < num_observables; ++m) { - std::size_t row_weight = obs_fb_offsets[m + 1] - obs_fb_offsets[m]; - std::size_t idx = num_rounds * obs_fb_offsets[m] + round * row_weight; - for (std::size_t i = obs_fb_offsets[m]; i < obs_fb_offsets[m + 1]; ++i) - obs_fb_records[idx++] = syndrome[obs_fb_indices[i]]; - } - } - if (fb_offsets.size() == 0) { + if (obs_feedback_flat.size() > 0) + collect_observable_feedback_round(obs_fb_records, obs_fb_offsets, + syndrome, round, obs_feedback_flat, + num_observables, numCols); + if (feedback_flat.size() == 0) { cudaq::detectors(final_syndrome, syndrome); } else { // Cross-round detector for record j: earlier vs current round record, - // augmented with the earlier-round herald records in row j of the - // feedback layout. - for (std::size_t j = 0; j < numCols; ++j) { - std::size_t begin = fb_offsets[j]; - std::size_t end = fb_offsets[j + 1]; - std::vector det(2 + end - begin); - det[0] = final_syndrome[j]; - det[1] = syndrome[j]; - for (std::size_t i = begin; i < end; ++i) - det[2 + (i - begin)] = final_syndrome[fb_indices[i]]; - cudaq::detector(det); - } + // augmented with the earlier-round records declared in row j of the + // feedback matrix. + for (std::size_t j = 0; j < numCols; ++j) + cudaq::detector(cross_round_detector_records( + final_syndrome, syndrome, j, feedback_flat, numCols)); } final_syndrome = syndrome; } @@ -101,76 +85,23 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, } auto data_results = mz(data); - // Emit one logical_observable per row of the observable matrix. - for (std::size_t obs = 0; obs < num_observables; ++obs) { - std::size_t support_weight = 0; - for (std::size_t q = 0; q < num_data; ++q) { - if (obs_matrix_flat[obs * num_data + q] != 0) - support_weight++; - } - if (!has_obs_fb) { - std::vector obs_support(support_weight); - std::size_t idx = 0; - for (std::size_t q = 0; q < num_data; ++q) { - if (obs_matrix_flat[obs * num_data + q] != 0) - obs_support[idx++] = data_results[q]; - } - cudaq::logical_observable(obs_support); - } else { - // Feedback records from every round, then the data-qubit support. - std::size_t row_weight = obs_fb_offsets[obs + 1] - obs_fb_offsets[obs]; - std::size_t fb_count = num_rounds * row_weight; - std::size_t base = num_rounds * obs_fb_offsets[obs]; - std::vector obs_support(fb_count + support_weight); - for (std::size_t i = 0; i < fb_count; ++i) - obs_support[i] = obs_fb_records[base + i]; - std::size_t idx = fb_count; - for (std::size_t q = 0; q < num_data; ++q) { - if (obs_matrix_flat[obs * num_data + q] != 0) - obs_support[idx++] = data_results[q]; - } - cudaq::logical_observable(obs_support); - } - } + // Emit one logical_observable per row of the observable matrix: the per-round + // feedback records followed by the data-qubit support. + for (std::size_t obs = 0; obs < num_observables; ++obs) + cudaq::logical_observable( + observable_support_records(obs, obs_matrix_flat, num_data, data_results, + obs_fb_records, obs_fb_offsets)); // For each stabilizer, form detectors from data qubit readout connected with - // final stabilizer round. + // final stabilizer round. With inlined feedback, the boundary detector for + // record (fixed_offset + x) is extended with the declared last-round records. const std::vector &stabilizers = measure_in_x_basis ? x_stabilizers : z_stabilizers; - for (std::size_t x = 0; x < num_fixed_measurements; ++x) { - std::size_t row_base = x * num_data; - - std::size_t support_weight = 0; - for (std::size_t q = 0; q < num_data; ++q) { - if (stabilizers[row_base + q] != 0) { - support_weight++; - } - } - - // With inlined feedback, the boundary detector for record - // (fixed_offset + x) is extended with its declared last-round records. - std::size_t fb_begin = 0; - std::size_t fb_end = 0; - if (fb_offsets.size() > 0) { - fb_begin = fb_offsets[fixed_offset + x]; - fb_end = fb_offsets[fixed_offset + x + 1]; - } - - std::vector support(support_weight + 1 + - (fb_end - fb_begin)); - support[0] = final_syndrome[fixed_offset + x]; - std::size_t support_idx = 1; - for (std::size_t q = 0; q < num_data; ++q) { - if (stabilizers[row_base + q] != 0) { - support[support_idx++] = data_results[q]; - } - } - for (std::size_t i = fb_begin; i < fb_end; ++i) - support[support_idx++] = final_syndrome[fb_indices[i]]; - - cudaq::detector(support); - } + for (std::size_t x = 0; x < num_fixed_measurements; ++x) + cudaq::detector(boundary_detector_records( + final_syndrome, fixed_offset + x, data_results, stabilizers, + x * num_data, num_data, feedback_flat, numCols)); } } // namespace cudaq::qec diff --git a/libs/qec/lib/device/memory_circuit.h b/libs/qec/lib/device/memory_circuit.h index e21ac943b..a15b25842 100644 --- a/libs/qec/lib/device/memory_circuit.h +++ b/libs/qec/lib/device/memory_circuit.h @@ -29,20 +29,16 @@ namespace cudaq::qec { /// (num_observables × numData entries, values 0/1). /// @param num_observables Number of rows in the observable matrix (k). /// @param measure_in_x_basis Performing X- or Z-memory circuit -/// @param fb_indices CSR herald-column indices for the detector inlined -/// feedback layout. `fb_indices[fb_offsets[j] .. fb_offsets[j+1])` -/// lists the herald record columns XORed into record j's cross-round -/// detector (records of the earlier round) and into its final boundary -/// detector (records of the last round). -/// @param fb_offsets CSR row offsets for the detector inlined feedback layout. -/// Size is 0 (no feedback; legacy `cudaq::detectors` structure) or -/// numCols + 1 with numCols = numAncx + numAncz. -/// @param obs_fb_indices CSR record-column indices for the observable inlined -/// feedback layout. `obs_fb_indices[obs_fb_offsets[m] .. -/// obs_fb_offsets[m+1])` lists the record columns XORed into logical -/// observable m on every round. -/// @param obs_fb_offsets CSR row offsets for the observable inlined feedback -/// layout. Size is 0 (no feedback) or num_observables + 1. +/// @param feedback_flat Row-major flattened inlined feedback matrix for +/// detectors. Size is 0 (no feedback; legacy detector structure) or +/// numCols*numCols with numCols = numAncx + numAncz. Entry (j, k) = 1 +/// means the cross-round detector for record j additionally XORs +/// record k of the earlier round, and the final boundary detector for +/// record j additionally XORs record k of the last round. +/// @param obs_feedback_flat Row-major flattened inlined feedback matrix for +/// logical observables. Size is 0 (no feedback) or +/// num_observables*numCols. Entry (m, k) = 1 means logical observable +/// m additionally XORs record k of every round. __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const code::one_qubit_encoding &statePrep, std::size_t numData, std::size_t numAncx, @@ -52,8 +48,6 @@ __qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, const std::vector &obs_matrix_flat, std::size_t num_observables, bool measure_in_x_basis, - const std::vector &fb_indices, - const std::vector &fb_offsets, - const std::vector &obs_fb_indices, - const std::vector &obs_fb_offsets); + const std::vector &feedback_flat, + const std::vector &obs_feedback_flat); } // namespace cudaq::qec diff --git a/libs/qec/lib/experiments.cpp b/libs/qec/lib/experiments.cpp index 39a465475..efb9add83 100644 --- a/libs/qec/lib/experiments.cpp +++ b/libs/qec/lib/experiments.cpp @@ -254,6 +254,29 @@ stabilizer_detector_ranges(std::size_t numRounds, std::size_t numZStabs, return ranges; } +/// @brief Validate and flatten (row-major) an inlined feedback tensor +/// declared by a code. An empty tensor (the identity default) flattens to an +/// empty vector; a non-empty tensor must have shape +/// [expected_rows, expected_cols]. +static std::vector +flatten_feedback_tensor(const cudaqx::tensor &t, + std::size_t expected_rows, std::size_t expected_cols, + const std::string &name) { + if (t.size() == 0) + return {}; + if (t.rank() != 2 || t.shape()[0] != expected_rows || + t.shape()[1] != expected_cols) { + std::string actual; + for (std::size_t d = 0; d < t.rank(); ++d) + actual += (d ? ", " : "") + std::to_string(t.shape()[d]); + throw std::runtime_error(name + " has invalid shape [" + actual + + "] - expected [" + std::to_string(expected_rows) + + ", " + std::to_string(expected_cols) + + "] or an empty tensor."); + } + return std::vector(t.data(), t.data() + t.size()); +} + /// @brief Given a memory circuit setup, sample syndrome and data qubit /// measurements. This is the main driver function that all of the /// sample_memory_circuit overloads invoke. @@ -309,29 +332,29 @@ sample_memory_circuit(const code &code, operation statePrep, const std::size_t numCols = numAncx + numAncz; - auto fb_layout = apply_inlined_feedback( - code.get_inlined_feedback(), code.get_observable_inlined_feedback(), - numCols, num_obs); + auto feedback_flat = flatten_feedback_tensor( + code.get_inlined_feedback(), numCols, numCols, "get_inlined_feedback()"); + auto obs_feedback_flat = + flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, + numCols, "get_observable_inlined_feedback()"); // Obtain the Measurement-to-Detector (M2D) sparse matrix. // m2d.rows[d] = set of chronological measurement indices whose XOR = detector // d. cudaq::M2DSparseMatrix m2d; cudaq::M2OSparseMatrix m2o; - cudaq::dem_from_kernel( - memory_circuit, &noise, /*options=*/{}, m2d, m2o, stabRound, prep, - numData, numAncx, numAncz, numRounds, xVec, zVec, obs_flat, num_obs, - !is_z_prep, fb_layout.detector_indices, fb_layout.detector_offsets, - fb_layout.observable_indices, fb_layout.observable_offsets); + cudaq::dem_from_kernel(memory_circuit, &noise, /*options=*/{}, m2d, m2o, + stabRound, prep, numData, numAncx, numAncz, numRounds, + xVec, zVec, obs_flat, num_obs, !is_z_prep, + feedback_flat, obs_feedback_flat); // Sample the memory circuit and collect all raw measurements. cudaq::sample_options opts{ .shots = numShots, .noise = noise, .explicit_measurements = true}; - auto result = cudaq::sample( - opts, memory_circuit, stabRound, prep, numData, numAncx, numAncz, - numRounds, xVec, zVec, obs_flat, num_obs, !is_z_prep, - fb_layout.detector_indices, fb_layout.detector_offsets, - fb_layout.observable_indices, fb_layout.observable_offsets); + auto result = + cudaq::sample(opts, memory_circuit, stabRound, prep, numData, numAncx, + numAncz, numRounds, xVec, zVec, obs_flat, num_obs, + !is_z_prep, feedback_flat, obs_feedback_flat); // mzTable[shot, meas_idx] = raw 0/1 outcome; shape (numShots, // numMeasPerShot). Measurement layout per shot: numRounds*numCols ancilla, @@ -488,17 +511,18 @@ dem_from_memory_circuit(const code &code, operation statePrep, logical_obs.data() + logical_obs.size()); const std::size_t numAnc = numAncx + numAncz; - auto fb_layout = apply_inlined_feedback( - code.get_inlined_feedback(), code.get_observable_inlined_feedback(), - numAnc, num_obs); + auto feedback_flat = flatten_feedback_tensor( + code.get_inlined_feedback(), numAnc, numAnc, "get_inlined_feedback()"); + auto obs_feedback_flat = + flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, + numAnc, "get_observable_inlined_feedback()"); cudaq::dem_options dem_opts; dem_opts.decompose_errors = decompose_errors; auto dem_text = cudaq::dem_from_kernel( memory_circuit, &noise, dem_opts, stabRound, prep, numData, numAncx, numAncz, numRounds, xVec, zVec, obs_flat, num_obs, !is_z_prep, - fb_layout.detector_indices, fb_layout.detector_offsets, - fb_layout.observable_indices, fb_layout.observable_offsets); + feedback_flat, obs_feedback_flat); auto dem = cudaq::qec::dem_from_stim_text(dem_text, decompose_errors); const auto numXStabs = code.get_num_x_stabilizers(); diff --git a/libs/qec/unittests/test_qec.cpp b/libs/qec/unittests/test_qec.cpp index 429f960b3..7bba70357 100644 --- a/libs/qec/unittests/test_qec.cpp +++ b/libs/qec/unittests/test_qec.cpp @@ -11,9 +11,11 @@ #include #include #include +#include #include #include "cuda-qx/core/library_utils.h" +#include "cudaq/algorithms/dem.h" #include "cudaq/qec/codes/surface_code.h" #include "cudaq/qec/experiments.h" #include "cudaq/qec/pcm_utils.h" @@ -2362,7 +2364,7 @@ TEST(QECCodeTester, checkInlinedFeedbackToyDem) { TEST(InlinedFeedbackLayout, EmptyTensorsGiveEmptyLayout) { cudaqx::tensor empty; - auto layout = cudaq::qec::apply_inlined_feedback(empty, empty, 2, 1); + auto layout = cudaq::qec::build_inlined_feedback_layout(empty, empty, 2, 1); EXPECT_TRUE(layout.detector_indices.empty()); EXPECT_TRUE(layout.detector_offsets.empty()); EXPECT_TRUE(layout.observable_indices.empty()); @@ -2376,7 +2378,7 @@ TEST(InlinedFeedbackLayout, ToyMatricesCsr) { // obs_fb = [[0,1]]: observable 0 XORs record 1 every round. cudaqx::tensor obs_fb({1, 2}); obs_fb.at({0, 1}) = 1; - auto layout = cudaq::qec::apply_inlined_feedback(fb, obs_fb, 2, 1); + auto layout = cudaq::qec::build_inlined_feedback_layout(fb, obs_fb, 2, 1); EXPECT_EQ(layout.detector_indices, (std::vector{1})); EXPECT_EQ(layout.detector_offsets, (std::vector{0, 1, 1})); EXPECT_EQ(layout.observable_indices, (std::vector{1})); @@ -2390,7 +2392,7 @@ TEST(InlinedFeedbackLayout, MultiRowWeights) { fb.at({0, 2}) = 1; fb.at({2, 1}) = 1; cudaqx::tensor empty; - auto layout = cudaq::qec::apply_inlined_feedback(fb, empty, 3, 0); + auto layout = cudaq::qec::build_inlined_feedback_layout(fb, empty, 3, 0); EXPECT_EQ(layout.detector_indices, (std::vector{0, 2, 1})); EXPECT_EQ(layout.detector_offsets, (std::vector{0, 2, 2, 3})); EXPECT_TRUE(layout.observable_offsets.empty()); @@ -2399,7 +2401,7 @@ TEST(InlinedFeedbackLayout, MultiRowWeights) { TEST(InlinedFeedbackLayout, AllZeroMatrixGivesZeroWeightRows) { cudaqx::tensor fb({2, 2}); cudaqx::tensor empty; - auto layout = cudaq::qec::apply_inlined_feedback(fb, empty, 2, 0); + auto layout = cudaq::qec::build_inlined_feedback_layout(fb, empty, 2, 0); EXPECT_TRUE(layout.detector_indices.empty()); EXPECT_EQ(layout.detector_offsets, (std::vector{0, 0, 0})); } @@ -2407,9 +2409,126 @@ TEST(InlinedFeedbackLayout, AllZeroMatrixGivesZeroWeightRows) { TEST(InlinedFeedbackLayout, ThrowsOnWrongShape) { cudaqx::tensor bad({2, 3}); // expected [2 x 2] cudaqx::tensor empty; - EXPECT_THROW(cudaq::qec::apply_inlined_feedback(bad, empty, 2, 0), + EXPECT_THROW(cudaq::qec::build_inlined_feedback_layout(bad, empty, 2, 0), std::runtime_error); cudaqx::tensor bad_obs({2, 2}); // expected [1 x 2] - EXPECT_THROW(cudaq::qec::apply_inlined_feedback(empty, bad_obs, 2, 1), + EXPECT_THROW(cudaq::qec::build_inlined_feedback_layout(empty, bad_obs, 2, 1), std::runtime_error); } + +// The entry-point memory-circuit kernel (defined in device/memory_circuit.cpp); +// forward-declared here - like the feedback_toy kernels above - so the +// conformance test below can drive dem_from_kernel directly. +namespace cudaq::qec { +__qpu__ void memory_circuit(const code::stabilizer_round &stabilizer_round, + const code::one_qubit_encoding &statePrep, + std::size_t numData, std::size_t numAncx, + std::size_t numAncz, std::size_t numRounds, + const std::vector &x_stabilizers, + const std::vector &z_stabilizers, + const std::vector &obs_matrix_flat, + std::size_t num_observables, + bool measure_in_x_basis, + const std::vector &feedback_flat, + const std::vector &obs_feedback_flat); +} // namespace cudaq::qec + +// Conformance: the device fold inside memory_circuit and the host-side rule in +// build_inlined_feedback_layout must agree on which records compose each +// detector. Build the measurements-to-detectors matrix (M2D) from the kernel +// and compare it, row by row, against the M2D reconstructed from the host +// layout plus the known emission order. If either the device fold or the host +// layout drifts, this test fails. +TEST(InlinedFeedbackLayout, HostLayoutMatchesKernelM2D) { + feedback_toy_code toy(/*declare_feedback=*/true); + const std::size_t numRounds = 4; + const std::size_t numData = 2, numAncx = 1, numAncz = 1; + const std::size_t numCols = numAncx + numAncz; // records per round + const std::size_t num_obs = 1; + + // --- Kernel-derived M2D, mirroring experiments.cpp's sample path. prep0 is a + // Z-basis memory, so measure_in_x_basis = false and the fixed records are the + // Z ancillas (fixed_offset = 0). --- + auto &prep = toy.get_operation( + cudaq::qec::operation::prep0); + auto &stabRound = toy.get_operation( + cudaq::qec::operation::stabilizer_round); + auto parity_x = toy.get_parity_x(); + auto parity_z = toy.get_parity_z(); + std::vector xVec(parity_x.data(), + parity_x.data() + parity_x.size()); + std::vector zVec(parity_z.data(), + parity_z.data() + parity_z.size()); + auto logical_obs = toy.get_observables_z(); + std::vector obs_flat(logical_obs.data(), + logical_obs.data() + logical_obs.size()); + + auto feedback = toy.get_inlined_feedback(); + auto obs_feedback = toy.get_observable_inlined_feedback(); + std::vector feedback_flat(feedback.data(), + feedback.data() + feedback.size()); + std::vector obs_feedback_flat( + obs_feedback.data(), obs_feedback.data() + obs_feedback.size()); + + cudaq::noise_model noise; + cudaq::M2DSparseMatrix m2d; + cudaq::M2OSparseMatrix m2o; + cudaq::dem_from_kernel( + cudaq::qec::memory_circuit, &noise, /*options=*/{}, m2d, m2o, stabRound, + prep, numData, numAncx, numAncz, numRounds, xVec, zVec, obs_flat, num_obs, + /*measure_in_x_basis=*/false, feedback_flat, obs_feedback_flat); + + // --- Host-layout-derived expected M2D. Global record index for round r, + // column c is r*numCols + c; the readout for data qubit q is at + // numRounds*numCols + q. --- + auto layout = cudaq::qec::build_inlined_feedback_layout( + feedback, obs_feedback, numCols, num_obs); + auto rec = [numCols](std::size_t round, std::size_t col) { + return round * numCols + col; + }; + auto herald_cols = [](const std::vector &indices, + const std::vector &offsets, + std::size_t row) { + std::vector cols; + if (!offsets.empty()) + cols.assign(indices.begin() + offsets[row], + indices.begin() + offsets[row + 1]); + return cols; + }; + + std::vector> expected; + // Round-0 fixed detector: the fixed record (fixed_offset + 0) of round 0. + expected.push_back({rec(0, 0)}); + // Interior cross-round detectors, emitted each round for j = 0..numCols-1: + // {prev_j, curr_j} plus the layout-row-j heralds taken from the earlier + // round. + for (std::size_t r = 1; r < numRounds; ++r) { + for (std::size_t j = 0; j < numCols; ++j) { + std::set row{rec(r - 1, j), rec(r, j)}; + for (auto k : + herald_cols(layout.detector_indices, layout.detector_offsets, j)) + row.insert(rec(r - 1, k)); + expected.push_back(row); + } + } + // Final boundary detector for the fixed record (row 0): the last-round fixed + // record, the data readouts in the stabilizer support, and the layout-row-0 + // heralds taken from the last round. + { + std::set row{rec(numRounds - 1, 0)}; + for (std::size_t q = 0; q < numData; ++q) + if (zVec[q] != 0) + row.insert(numRounds * numCols + q); + for (auto k : + herald_cols(layout.detector_indices, layout.detector_offsets, 0)) + row.insert(rec(numRounds - 1, k)); + expected.push_back(row); + } + + ASSERT_EQ(m2d.rows.size(), 2 * numRounds); + ASSERT_EQ(m2d.rows.size(), expected.size()); + for (std::size_t d = 0; d < expected.size(); ++d) { + std::set actual(m2d.rows[d].begin(), m2d.rows[d].end()); + EXPECT_EQ(actual, expected[d]) << "detector " << d; + } +} From 43b6bd18464b7c8aaaa69c0e216fca52b9a464c7 Mon Sep 17 00:00:00 2001 From: kvmto Date: Sat, 11 Jul 2026 03:07:04 +0200 Subject: [PATCH 4/8] split between two types of stabiizer Signed-off-by: kvmto --- libs/qec/include/cudaq/qec/code.h | 29 +++++++-- libs/qec/lib/code.cpp | 6 +- libs/qec/lib/experiments.cpp | 18 ++++-- libs/qec/python/bindings/py_code.cpp | 37 ++++++++--- libs/qec/python/tests/test_code.py | 67 +++++++++++++++++++- libs/qec/unittests/test_qec.cpp | 94 ++++++++++++++++++++++++++-- 6 files changed, 221 insertions(+), 30 deletions(-) diff --git a/libs/qec/include/cudaq/qec/code.h b/libs/qec/include/cudaq/qec/code.h index 3a9eefce7..e41177a76 100644 --- a/libs/qec/include/cudaq/qec/code.h +++ b/libs/qec/include/cudaq/qec/code.h @@ -214,16 +214,33 @@ class code : public cudaqx::extension_point { /// formed from same-record comparisons only. virtual cudaqx::tensor get_inlined_feedback() const; - /// @brief Get the inlined feedback matrix for logical observables + /// @brief Get the inlined feedback matrix for logical observables measured + /// in the Z basis /// /// Shape is [num_observables x numCols], where numCols = /// get_num_ancilla_qubits() (one measurement record per ancilla per /// round, in [Z][X] order). Entry (m, k) = 1 means logical observable m - /// additionally XORs record k of every round. - /// @return Tensor representing the observable inlined feedback matrix. - /// An empty tensor (the default) means no feedback is applied to the - /// logical observables. - virtual cudaqx::tensor get_observable_inlined_feedback() const; + /// additionally XORs record k of every round. This getter is consumed when + /// the memory experiment measures its observables in the Z basis (prep0 / + /// prep1 state preparations). + /// @return Tensor representing the Z-basis observable inlined feedback + /// matrix. An empty tensor (the default) means no observable feedback is + /// applied in the Z basis. + virtual cudaqx::tensor get_observable_inlined_feedback_z() const; + + /// @brief Get the inlined feedback matrix for logical observables measured + /// in the X basis + /// + /// Shape is [num_observables x numCols], where numCols = + /// get_num_ancilla_qubits() (one measurement record per ancilla per + /// round, in [Z][X] order). Entry (m, k) = 1 means logical observable m + /// additionally XORs record k of every round. This getter is consumed when + /// the memory experiment measures its observables in the X basis (prepp / + /// prepm state preparations). + /// @return Tensor representing the X-basis observable inlined feedback + /// matrix. An empty tensor (the default) means no observable feedback is + /// applied in the X basis. + virtual cudaqx::tensor get_observable_inlined_feedback_x() const; /// @brief Get the stabilizer generators /// @return Reference to stabilizers diff --git a/libs/qec/lib/code.cpp b/libs/qec/lib/code.cpp index bb6b720a6..39be5efed 100644 --- a/libs/qec/lib/code.cpp +++ b/libs/qec/lib/code.cpp @@ -65,7 +65,11 @@ cudaqx::tensor code::get_inlined_feedback() const { return cudaqx::tensor(); } -cudaqx::tensor code::get_observable_inlined_feedback() const { +cudaqx::tensor code::get_observable_inlined_feedback_z() const { + return cudaqx::tensor(); +} + +cudaqx::tensor code::get_observable_inlined_feedback_x() const { return cudaqx::tensor(); } diff --git a/libs/qec/lib/experiments.cpp b/libs/qec/lib/experiments.cpp index efb9add83..d4a9f1780 100644 --- a/libs/qec/lib/experiments.cpp +++ b/libs/qec/lib/experiments.cpp @@ -334,9 +334,12 @@ sample_memory_circuit(const code &code, operation statePrep, auto feedback_flat = flatten_feedback_tensor( code.get_inlined_feedback(), numCols, numCols, "get_inlined_feedback()"); - auto obs_feedback_flat = - flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, - numCols, "get_observable_inlined_feedback()"); + auto obs_feedback_flat = flatten_feedback_tensor( + is_z_prep ? code.get_observable_inlined_feedback_z() + : code.get_observable_inlined_feedback_x(), + num_obs, numCols, + is_z_prep ? "get_observable_inlined_feedback_z()" + : "get_observable_inlined_feedback_x()"); // Obtain the Measurement-to-Detector (M2D) sparse matrix. // m2d.rows[d] = set of chronological measurement indices whose XOR = detector @@ -513,9 +516,12 @@ dem_from_memory_circuit(const code &code, operation statePrep, const std::size_t numAnc = numAncx + numAncz; auto feedback_flat = flatten_feedback_tensor( code.get_inlined_feedback(), numAnc, numAnc, "get_inlined_feedback()"); - auto obs_feedback_flat = - flatten_feedback_tensor(code.get_observable_inlined_feedback(), num_obs, - numAnc, "get_observable_inlined_feedback()"); + auto obs_feedback_flat = flatten_feedback_tensor( + is_z_prep ? code.get_observable_inlined_feedback_z() + : code.get_observable_inlined_feedback_x(), + num_obs, numAnc, + is_z_prep ? "get_observable_inlined_feedback_z()" + : "get_observable_inlined_feedback_x()"); cudaq::dem_options dem_opts; dem_opts.decompose_errors = decompose_errors; diff --git a/libs/qec/python/bindings/py_code.cpp b/libs/qec/python/bindings/py_code.cpp index 3c63816b6..52a59b43b 100644 --- a/libs/qec/python/bindings/py_code.cpp +++ b/libs/qec/python/bindings/py_code.cpp @@ -51,7 +51,7 @@ static cudaqx::tensor feedbackArrayToTensor(nb::object array, class PyCode : public qec::code { public: - NB_TRAMPOLINE(qec::code, 8); + NB_TRAMPOLINE(qec::code, 9); protected: // Trampoline methods for the optional inlined-feedback virtuals: forward to @@ -66,13 +66,22 @@ class PyCode : public qec::code { return NBBase::get_inlined_feedback(); } - cudaqx::tensor get_observable_inlined_feedback() const override { + cudaqx::tensor get_observable_inlined_feedback_z() const override { nb::detail::ticket nb_ticket(nb_trampoline, - "get_observable_inlined_feedback", false); + "get_observable_inlined_feedback_z", false); if (nb_ticket.key.is_valid()) return feedbackArrayToTensor(nb_trampoline.base().attr(nb_ticket.key)(), - "get_observable_inlined_feedback"); - return NBBase::get_observable_inlined_feedback(); + "get_observable_inlined_feedback_z"); + return NBBase::get_observable_inlined_feedback_z(); + } + + cudaqx::tensor get_observable_inlined_feedback_x() const override { + nb::detail::ticket nb_ticket(nb_trampoline, + "get_observable_inlined_feedback_x", false); + if (nb_ticket.key.is_valid()) + return feedbackArrayToTensor(nb_trampoline.base().attr(nb_ticket.key)(), + "get_observable_inlined_feedback_x"); + return NBBase::get_observable_inlined_feedback_x(); } // Trampoline methods for pure virtual functions @@ -237,12 +246,20 @@ class PyCodeHandle : public qec::code { "get_inlined_feedback"); } - cudaqx::tensor get_observable_inlined_feedback() const override { - if (!nb::hasattr(pyCode, "get_observable_inlined_feedback")) - return code::get_observable_inlined_feedback(); + cudaqx::tensor get_observable_inlined_feedback_z() const override { + if (!nb::hasattr(pyCode, "get_observable_inlined_feedback_z")) + return code::get_observable_inlined_feedback_z(); + return feedbackArrayToTensor( + pyCode.attr("get_observable_inlined_feedback_z")(), + "get_observable_inlined_feedback_z"); + } + + cudaqx::tensor get_observable_inlined_feedback_x() const override { + if (!nb::hasattr(pyCode, "get_observable_inlined_feedback_x")) + return code::get_observable_inlined_feedback_x(); return feedbackArrayToTensor( - pyCode.attr("get_observable_inlined_feedback")(), - "get_observable_inlined_feedback"); + pyCode.attr("get_observable_inlined_feedback_x")(), + "get_observable_inlined_feedback_x"); } protected: diff --git a/libs/qec/python/tests/test_code.py b/libs/qec/python/tests/test_code.py index 0ba39a425..0a08c3bc4 100644 --- a/libs/qec/python/tests/test_code.py +++ b/libs/qec/python/tests/test_code.py @@ -392,7 +392,7 @@ def get_num_z_stabilizers(self): def get_inlined_feedback(self): return np.array([[0, 1], [0, 0]], dtype=np.uint8) - def get_observable_inlined_feedback(self): + def get_observable_inlined_feedback_z(self): # Exercise the bridge's dtype coercion: int64 instead of uint8. return np.array([[0, 1]]) @@ -473,5 +473,70 @@ def get_num_z_stabilizers(self): numRounds=4) +def test_python_inlined_feedback_observable_basis_selection(): + # The bridge routes get_observable_inlined_feedback_x to the X-basis getter, + # so it is never queried on the Z (prep0) path. Plant a deliberately + # wrong-shape _x matrix alongside a valid _z matrix: were the bridge to feed + # _x into the Z path, flatten_feedback_tensor's shape check would reject the + # circuit. The toy registers only prep0, so this proves selection from the + # Z path (the wrong-shape _x is inert there). + @qec.code('py-feedback-toy-basis-select') + class FeedbackToyBasisSelect: + + def __init__(self): + qec.Code.__init__(self) + self.stabilizers = [ + cudaq.SpinOperator.from_word(w) for w in ["XX", "ZZ"] + ] + self.pauli_observables = [cudaq.SpinOperator.from_word("ZZ")] + self.operation_encodings = { + qec.operation.prep0: _feedback_toy_prep0, + qec.operation.stabilizer_round: _feedback_toy_round + } + + def get_num_data_qubits(self): + return 2 + + def get_num_ancilla_qubits(self): + return 2 + + def get_num_ancilla_x_qubits(self): + return 1 + + def get_num_ancilla_z_qubits(self): + return 1 + + def get_num_x_stabilizers(self): + return 1 + + def get_num_z_stabilizers(self): + return 1 + + def get_inlined_feedback(self): + return np.array([[0, 1], [0, 0]], dtype=np.uint8) + + def get_observable_inlined_feedback_z(self): + return np.array([[0, 1]], dtype=np.uint8) + + def get_observable_inlined_feedback_x(self): + # Wrong shape for [num_obs=1 x numCols=2]; must never reach the + # Z-basis flatten on the prep0 path. + return np.zeros((3, 5), dtype=np.uint8) + + cudaq.set_target('stim') + try: + numShots, numRounds = 20, 4 + syndromes, data = qec.sample_memory_circuit( + qec.get_code('py-feedback-toy-basis-select'), + numShots=numShots, + numRounds=numRounds) + assert syndromes.shape == (numShots, 2 * numRounds) + assert not np.any(syndromes) + assert data.shape == (numShots, 2) + assert not np.any(data[:, 0] ^ data[:, 1]) + finally: + cudaq.reset_target() + + if __name__ == "__main__": pytest.main() diff --git a/libs/qec/unittests/test_qec.cpp b/libs/qec/unittests/test_qec.cpp index 7bba70357..4b44344d8 100644 --- a/libs/qec/unittests/test_qec.cpp +++ b/libs/qec/unittests/test_qec.cpp @@ -2200,9 +2200,12 @@ TEST(QECCodeTester, checkInlinedFeedbackDefaults) { auto feedback = steane->get_inlined_feedback(); EXPECT_EQ(feedback.rank(), 0); EXPECT_EQ(feedback.size(), 0); - auto obs_feedback = steane->get_observable_inlined_feedback(); - EXPECT_EQ(obs_feedback.rank(), 0); - EXPECT_EQ(obs_feedback.size(), 0); + auto obs_feedback_z = steane->get_observable_inlined_feedback_z(); + EXPECT_EQ(obs_feedback_z.rank(), 0); + EXPECT_EQ(obs_feedback_z.size(), 0); + auto obs_feedback_x = steane->get_observable_inlined_feedback_x(); + EXPECT_EQ(obs_feedback_x.rank(), 0); + EXPECT_EQ(obs_feedback_x.size(), 0); } // Device kernels for the inlined-feedback toy code, nvq++-compiled in @@ -2287,15 +2290,38 @@ class feedback_toy_code : public cudaq::qec::code { return feedback; } - cudaqx::tensor get_observable_inlined_feedback() const override { + cudaqx::tensor get_observable_inlined_feedback_z() const override { if (!declare_feedback) - return code::get_observable_inlined_feedback(); + return code::get_observable_inlined_feedback_z(); cudaqx::tensor feedback({1, 2}); feedback.at({0, 1}) = 1; return feedback; } }; +// Basis-selection variant of the toy: returns caller-planted observable- +// feedback matrices for the two bases so a test can put a deliberately +// wrong-shape matrix on the basis it expects sample_memory_circuit NOT to +// query. The detector feedback (get_inlined_feedback) stays valid, so the +// underlying Z-memory circuit is otherwise identical to the positive toy. +class feedback_toy_basis_select_code : public feedback_toy_code { + cudaqx::tensor m_obs_z; + cudaqx::tensor m_obs_x; + +public: + feedback_toy_basis_select_code(cudaqx::tensor obs_z, + cudaqx::tensor obs_x) + : feedback_toy_code(/*declare_feedback=*/true), m_obs_z(std::move(obs_z)), + m_obs_x(std::move(obs_x)) {} + + cudaqx::tensor get_observable_inlined_feedback_z() const override { + return m_obs_z; + } + cudaqx::tensor get_observable_inlined_feedback_x() const override { + return m_obs_x; + } +}; + } // namespace TEST(QECCodeTester, checkInlinedFeedbackToyMemoryCircuit) { @@ -2324,6 +2350,62 @@ TEST(QECCodeTester, checkInlinedFeedbackToyMemoryCircuit) { EXPECT_EQ(data.at({shot, 0}) ^ data.at({shot, 1}), 0) << "shot " << shot; } +TEST(QECCodeTester, checkInlinedFeedbackObservableBasisSelection) { + // The observable-feedback getter must be selected by the memory basis: a + // Z-basis (prep0) memory queries only get_observable_inlined_feedback_z() + // and never get_observable_inlined_feedback_x(). The toy device kernels + // register only prep0, so selection is proved from the Z path in both + // directions. + auto valid_obs = [] { + cudaqx::tensor t({1, 2}); + t.at({0, 1}) = 1; + return t; + }; + // Non-empty and the wrong shape for [num_obs=1 x numCols=2], so any code that + // flattens it trips flatten_feedback_tensor's shape check. + auto wrong_shape_obs = [] { return cudaqx::tensor({3, 5}); }; + + // (a) Valid Z matrix, deliberately wrong-shape X matrix: the Z-memory run + // must succeed exactly as the positive toy test, proving the X getter is + // never queried on the Z path. + { + feedback_toy_basis_select_code toy(valid_obs(), wrong_shape_obs()); + const std::size_t numShots = 20; + const std::size_t numRounds = 4; + auto [syndromes, data] = cudaq::qec::sample_memory_circuit( + toy, cudaq::qec::operation::prep0, numShots, numRounds); + ASSERT_EQ(syndromes.rank(), 2); + ASSERT_EQ(syndromes.shape()[0], numShots); + ASSERT_EQ(syndromes.shape()[1], 2 * numRounds); + for (std::size_t shot = 0; shot < numShots; ++shot) + for (std::size_t d = 0; d < syndromes.shape()[1]; ++d) + EXPECT_EQ(syndromes.at({shot, d}), 0) + << "shot " << shot << ", detector " << d; + ASSERT_EQ(data.shape()[0], numShots); + ASSERT_EQ(data.shape()[1], 2); + for (std::size_t shot = 0; shot < numShots; ++shot) + EXPECT_EQ(data.at({shot, 0}) ^ data.at({shot, 1}), 0) << "shot " << shot; + } + + // (converse) Wrong-shape Z matrix, valid X matrix: the same Z-memory run + // must now throw the shape-validation error, proving the Z getter IS the one + // queried on the Z path (the valid X matrix is irrelevant here). + { + feedback_toy_basis_select_code toy(wrong_shape_obs(), valid_obs()); + try { + cudaq::qec::sample_memory_circuit(toy, cudaq::qec::operation::prep0, + /*numShots=*/20, /*numRounds=*/4); + FAIL() << "expected sample_memory_circuit to reject the wrong-shape " + "Z-basis observable feedback"; + } catch (const std::exception &e) { + EXPECT_NE(std::string(e.what()).find( + "get_observable_inlined_feedback_z() has invalid shape"), + std::string::npos) + << "unexpected failure reason: " << e.what(); + } + } +} + TEST(QECCodeTester, checkInlinedFeedbackToyNegativeControl) { // The identical toy without the feedback declaration: the uncorrected // byproduct makes the record-0 detectors non-deterministic and stim must @@ -2464,7 +2546,7 @@ TEST(InlinedFeedbackLayout, HostLayoutMatchesKernelM2D) { logical_obs.data() + logical_obs.size()); auto feedback = toy.get_inlined_feedback(); - auto obs_feedback = toy.get_observable_inlined_feedback(); + auto obs_feedback = toy.get_observable_inlined_feedback_z(); std::vector feedback_flat(feedback.data(), feedback.data() + feedback.size()); std::vector obs_feedback_flat( From fc7fc218645a5fc557944f4bad13c72a3a290870 Mon Sep 17 00:00:00 2001 From: kvmto Date: Tue, 7 Jul 2026 18:16:25 +0200 Subject: [PATCH 5/8] draft of color: Add triangular color code plugin with superdense memory circuit Registers the triangular color code as the Python plugin 'color_code' (geometry, CSS stabilizers/observables, patch kernels) and adds a superdense memory circuit for it: the paired-ancilla 8-CNOT-layer schedule with the measurement feedforward absorbed into explicit cudaq.detector / cudaq.logical_observable annotations. DEM extraction and detector-ordered sampling via cudaq.dem_from_kernel / cudaq.sample; validated against a reference stim construction (identical error mechanisms, both bases). Signed-off-by: kvmto --- .../cudaq_qec/plugins/codes/color_code.py | 1560 +++++++++++++++++ .../tests/data/superdense_golden_d3_r3_X.dem | 334 ++++ .../tests/data/superdense_golden_d3_r3_Z.dem | 303 ++++ libs/qec/python/tests/test_color_code.py | 650 +++++++ 4 files changed, 2847 insertions(+) create mode 100644 libs/qec/python/cudaq_qec/plugins/codes/color_code.py create mode 100644 libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem create mode 100644 libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem create mode 100644 libs/qec/python/tests/test_color_code.py diff --git a/libs/qec/python/cudaq_qec/plugins/codes/color_code.py b/libs/qec/python/cudaq_qec/plugins/codes/color_code.py new file mode 100644 index 000000000..c8c9b6cf1 --- /dev/null +++ b/libs/qec/python/cudaq_qec/plugins/codes/color_code.py @@ -0,0 +1,1560 @@ +# ============================================================================ # +# Copyright (c) 2026 NVIDIA Corporation & Affiliates. # +# All rights reserved. # +# # +# This source code and the accompanying materials are made available under # +# the terms of the Apache License 2.0 which accompanies this distribution. # +# ============================================================================ # +""" +Triangular Color Code with rectangular grid embedding for CNN pre-decoder. + +The data qubits are embedded in a (n_rows x n_cols) rectangular grid where: +- n_rows = d + (d-1)//2 +- n_cols = d + +Coordinate system: +- Top qubit (qubit 0) is always at (row=0, col=0) +- Row index decreases (more negative) going down the triangle +- Column is centered around 0, expanding symmetrically + +Syndrome-to-grid mapping: +- For all stabilizers EXCEPT right boundary: map to top-right data qubit +- For right boundary (red weight-4): map to top-left data qubit + +Reference plaquettes for verification: + +d=3 (7 data qubits, 3 plaquettes, 4x3 grid): + [0,1,2,3]: green (boundary) + [2,3,4,5]: blue (boundary) + [1,3,5,6]: red (boundary) + +d=5 (19 data qubits, 9 plaquettes, 7x5 grid): + [0,1,2,3]: green (boundary) + [2,3,4,5,7,8]: blue (bulk) + [1,3,5,6]: red (boundary) + [5,6,8,9,12,13]: green (bulk) + [7,8,11,12,15,16]: red (bulk) + [4,7,10,11]: green (boundary) + [10,11,14,15]: blue (boundary) + [12,13,16,17]: blue (boundary) + [9,13,17,18]: red (boundary) + +d=7 (37 data qubits, 18 plaquettes, 10x7 grid): + [0,1,2,3]: green (boundary) + [2,3,4,5,7,8]: blue (bulk) + [1,3,5,6]: red (boundary) + [5,6,8,9,12,13]: green (bulk) + [7,8,11,12,15,16]: red (bulk) + [4,7,10,11]: green (boundary) + [10,11,14,15,19,20]: blue (bulk) + [12,13,16,17,21,22]: blue (bulk) + [9,13,17,18]: red (boundary) + [14,19,24,25]: green (boundary) + [15,16,20,21,26,27]: green (bulk) + [17,18,22,23,28,29]: green (bulk) + [19,20,25,26,31,32]: red (bulk) + [21,22,27,28,33,34]: red (bulk) + [23,29,35,36]: red (boundary) + [24,25,30,31]: blue (boundary) + [26,27,32,33]: blue (boundary) + [28,29,34,35]: blue (boundary) +""" + +import numpy as np +from typing import Dict, List, Tuple, Optional + +import cudaq +import cudaq_qec as qec +from cudaq_qec import patch + + +class ColorCodeGeometry: + """ + Triangular color code with rectangular grid embedding. + + Qubit numbering (for distance d): + - Data qubits: [0, num_data) + - X-check ancillas: [num_data, num_data + num_plaquettes) + - Z-check ancillas: [num_data + num_plaquettes, num_data + 2*num_plaquettes) + + Data qubits are numbered top-to-bottom, left-to-right. + Ancillas are numbered by their mapped grid position (top-to-bottom, left-to-right). + + Args: + distance: Code distance (odd integer >= 3) + + Attributes: + data_qubits: Array of data qubit indices [0, num_data) + xcheck_qubits: Array of X-check ancilla indices + zcheck_qubits: Array of Z-check ancilla indices + stab_to_data_idx: Maps stabilizer index to data qubit grid position + """ + + def __init__(self, distance: int): + if distance < 3 or distance % 2 == 0: + raise ValueError("Distance must be odd and >= 3") + + self.distance = distance + self.n_rows = distance + (distance - 1) // 2 + self.n_cols = distance + self.num_data = (3 * distance * distance + 1) // 4 + self.num_plaquettes = (3 * (distance * distance - 1)) // 8 + + # Generate data qubit grid layout + self._generate_data_qubit_grid() + + # Generate plaquettes (stabilizers) algorithmically + self._generate_plaquettes() + + # Compute syndrome-to-data mapping and sort plaquettes by grid position + self._compute_syndrome_mapping_and_sort() + + # Create qubit index arrays (after sorting) + self.data_qubits = np.arange(self.num_data) + self.xcheck_qubits = np.arange(self.num_data, + self.num_data + self.num_plaquettes) + self.zcheck_qubits = np.arange(self.num_data + self.num_plaquettes, + self.num_data + 2 * self.num_plaquettes) + self.all_qubits = np.arange(self.num_data + 2 * self.num_plaquettes) + + # Find the logical operator support + self._find_logical_qubits() + + def _get_row_width(self, row_idx: int) -> int: + """Get number of qubits in a given row (0-indexed from top).""" + group = row_idx // 3 + pos = row_idx % 3 + return 2 * group + 1 if pos < 2 else 2 * group + 2 + + def _get_row_start_col(self, width: int) -> int: + """Get starting column for a row of given width (centered around 0).""" + return -(width // 2) + + def _generate_data_qubit_grid(self): + """Generate data qubit positions on rectangular grid.""" + self.qubit_to_coord = {} # qubit_id -> (row, col) + self.coord_to_qubit = {} # (row, col) -> qubit_id + self.grid_to_qubit = { + } # (grid_row, grid_col) -> qubit_id (0-indexed grid) + self.qubit_to_grid = {} # qubit_id -> (grid_row, grid_col) + + qubit_id = 0 + for row_idx in range(self.n_rows): + width = self._get_row_width(row_idx) + start_col = self._get_row_start_col(width) + row = -row_idx # User's coordinate: row 0 at top, negative going down + + for i in range(width): + col = start_col + i + + self.qubit_to_coord[qubit_id] = (row, col) + self.coord_to_qubit[(row, col)] = qubit_id + + # Also store 0-indexed grid position for CNN + grid_row = row_idx + grid_col = col + (self.n_cols // 2) + self.grid_to_qubit[(grid_row, grid_col)] = qubit_id + self.qubit_to_grid[qubit_id] = (grid_row, grid_col) + + qubit_id += 1 + + assert qubit_id == self.num_data, f"Expected {self.num_data} qubits, got {qubit_id}" + + def _try_pattern(self, row: int, col: int, + pattern: List[Tuple[int, int]]) -> Optional[List[int]]: + """Try to form a plaquette with given pattern from anchor position.""" + qubits = [] + for dr, dc in pattern: + pos = (row + dr, col + dc) + if pos in self.coord_to_qubit: + qubits.append(self.coord_to_qubit[pos]) + else: + return None + return sorted(qubits) + + def _generate_plaquettes(self): + """Generate plaquette connectivity algorithmically.""" + colors = ['green', 'blue', 'red'] + plaquettes = [] + added_plaqs = set() + used_bulk = {c: set() for c in colors} + + # Plaquette patterns (relative to anchor position) + pattern_w6 = [(0, 0), (0, 1), (-1, 0), (-1, 1), (-2, 0), + (-2, 1)] # 3x2 bulk + pattern_top = [(0, 0), (-1, 0), (-2, -1), (-2, 0)] # top cap + pattern_left = [(-2, 0), (-2, 1), (-1, 1), (0, 1)] # left boundary + pattern_right = [(-2, 0), (-2, 1), (-1, 0), (0, 0)] # right boundary + pattern_bottom = [(-1, 0), (-1, 1), (0, 0), (0, 1)] # bottom 2x2 + + def add_plaq(qubits, color, ptype, check_bulk_overlap=True): + key = tuple(sorted(qubits)) + if key in added_plaqs: + return False + if check_bulk_overlap and ptype == 'bulk': + if any(q in used_bulk[color] for q in qubits): + return False + used_bulk[color].update(qubits) + plaquettes.append((qubits, color, ptype)) + added_plaqs.add(key) + return True + + # 1. Top plaquette (green) - always qubits 0,1,2,3 + add_plaq([0, 1, 2, 3], 'green', 'boundary', False) + + # 2. Weight-6 bulk plaquettes + color_occurrence = {'green': 0, 'blue': 0, 'red': 0} + + for row_idx in range(2, self.n_rows - 2): + row = -row_idx + color = colors[row % 3] + occ = color_occurrence[color] + color_occurrence[color] += 1 + + # Compute valid column positions for this color + if color == 'green': + # Green: alternates between center+even offsets and odd offsets + if occ == 0: + valid_cols = [0] + elif occ % 2 == 1: # Odd occurrence: use odd offsets + valid_cols = sorted( + [c for c in range(-occ, occ + 1) if c % 2 != 0]) + else: # Even occurrence: use even offsets (including 0) + valid_cols = sorted( + [c for c in range(-occ, occ + 1) if c % 2 == 0]) + else: + # Blue/Red: start from -(occ+1), step by 2 + start = -(occ + 1) + num_plaqs = occ + 1 + valid_cols = [start + 2 * i for i in range(num_plaqs)] + + for col in valid_cols: + qubits = self._try_pattern(row, col, pattern_w6) + if qubits: + add_plaq(qubits, color, 'bulk', True) + + # 3. Left boundary (green) - every 3 rows starting from row_idx=3 + for row_idx in range(3, self.n_rows - 2, 3): + row = -row_idx + width = self._get_row_width(row_idx) + anchor_col = self._get_row_start_col(width) - 1 + qubits = self._try_pattern(row, anchor_col, pattern_left) + if qubits: + add_plaq(qubits, 'green', 'boundary', False) + + # 4. Right boundary (red) - every 3 rows starting from row_idx=1 + for row_idx in range(1, self.n_rows - 2, 3): + row = -row_idx + width = self._get_row_width(row_idx) + anchor_col = self._get_row_start_col(width) + width - 1 + qubits = self._try_pattern(row, anchor_col, pattern_right) + if qubits: + add_plaq(qubits, 'red', 'boundary', False) + + # 5. Bottom boundary (blue) - 2x2 blocks on second-to-last row, step by 2 + second_last_row_idx = self.n_rows - 2 + row = -second_last_row_idx + width = self._get_row_width(second_last_row_idx) + start_col = self._get_row_start_col(width) + for col in range(start_col, start_col + width - 1, 2): + qubits = self._try_pattern(row, col, pattern_bottom) + if qubits: + add_plaq(qubits, 'blue', 'boundary', False) + + # Store raw plaquettes temporarily (will be sorted later) + self._raw_plaquettes = plaquettes + + assert len(plaquettes) == self.num_plaquettes, \ + f"Expected {self.num_plaquettes} plaquettes, got {len(plaquettes)}" + + def _get_mapped_data_qubit(self, data_qubits: List[int], color: str, + ptype: str) -> int: + """ + Get the data qubit that a plaquette's syndrome maps to. + + Rules: + - Right boundary (red weight-4): top-left data qubit + - All others: top-right data qubit + """ + # Get coordinates for all data qubits in plaquette + coords = [(q, self.qubit_to_coord[q]) for q in data_qubits] + + # Find top row (highest, i.e., least negative) + top_row = max(c[0] for _, c in coords) + top_qubits = [(q, c) for q, c in coords if c[0] == top_row] + + # Determine if this is right boundary (red weight-4) + is_right_boundary = (color == 'red' and ptype == 'boundary') + + if is_right_boundary: + # Top-left: minimum column + return min(top_qubits, key=lambda x: x[1][1])[0] + else: + # Top-right: maximum column + return max(top_qubits, key=lambda x: x[1][1])[0] + + def _compute_syndrome_mapping_and_sort(self): + """Compute syndrome-to-data mapping and sort plaquettes by grid position.""" + # Compute mapped data qubit for each plaquette + plaq_with_mapping = [] + for qubits, color, ptype in self._raw_plaquettes: + mapped_qubit = self._get_mapped_data_qubit(qubits, color, ptype) + grid_pos = self.qubit_to_grid[mapped_qubit] + plaq_with_mapping.append({ + 'data_qubits': qubits, + 'color': color, + 'type': ptype, + 'weight': len(qubits), + 'mapped_qubit': mapped_qubit, + 'grid_pos': grid_pos, + }) + + # Sort by grid position: top-to-bottom (row), left-to-right (col) + plaq_with_mapping.sort( + key=lambda p: (p['grid_pos'][0], p['grid_pos'][1])) + + # Assign ancilla IDs based on sorted order + # X-ancilla at index i: num_data + i + # Z-ancilla at index i: num_data + num_plaquettes + i + self.plaquettes = [] + self.stab_to_data_idx = np.zeros(self.num_plaquettes, dtype=np.int32) + + for plaq_idx, plaq in enumerate(plaq_with_mapping): + x_ancilla_id = self.num_data + plaq_idx + z_ancilla_id = self.num_data + self.num_plaquettes + plaq_idx + + self.plaquettes.append({ + 'x_ancilla': x_ancilla_id, + 'z_ancilla': z_ancilla_id, + 'data_qubits': plaq['data_qubits'], + 'weight': plaq['weight'], + 'type': plaq['type'], + 'color': plaq['color'], + 'mapped_qubit': plaq['mapped_qubit'], + 'grid_pos': plaq['grid_pos'], + }) + + self.stab_to_data_idx[plaq_idx] = plaq['mapped_qubit'] + + # Clean up temporary storage + del self._raw_plaquettes + + def _find_logical_qubits(self): + """Find the data qubits supporting the logical X/Z operators. + + For the triangular color code, the minimal logical operator is the + bottom edge (blue boundary), which has exactly d qubits. + This is preferred over using all data qubits because: + - Measurement errors scale as O(d) instead of O(d²) + - No need for boundary detectors in memory experiments + + Parity-check and observable matrices are not stored here: the code + object returned by qec.get_code('color_code', ...) provides them in + the framework's canonical form via get_parity_x()/get_parity_z() + and get_observables_x()/get_observables_z(). + """ + # Find bottom edge qubits (the row with minimum row coordinate) + bottom_row = min( + self.qubit_to_coord[q][0] for q in range(self.num_data)) + self.logical_qubits = sorted([ + q for q in range(self.num_data) + if self.qubit_to_coord[q][0] == bottom_row + ]) + + def get_grid_array(self) -> np.ndarray: + """Return 2D array of qubit IDs on the grid (-1 for padding).""" + grid = np.full((self.n_rows, self.n_cols), -1, dtype=np.int32) + for qid, (grid_row, grid_col) in self.qubit_to_grid.items(): + grid[grid_row, grid_col] = qid + return grid + + def get_syndrome_grid_indices(self) -> np.ndarray: + """ + Return array mapping stabilizer index to flat grid index. + + For use with reshape_stabilizers_to_grid functions. + Returns array of shape (num_plaquettes,) where each entry is the + flat index (row * n_cols + col) into the n_rows x n_cols grid. + """ + indices = np.zeros(self.num_plaquettes, dtype=np.int32) + for i, plaq in enumerate(self.plaquettes): + grid_row, grid_col = plaq['grid_pos'] + indices[i] = grid_row * self.n_cols + grid_col + return indices + + def print_structure(self): + """Print code structure summary.""" + print(f"Triangular Color Code - Distance {self.distance}") + print(f" Grid size: {self.n_rows} x {self.n_cols}") + print(f" Data qubits: {self.num_data} (IDs: 0-{self.num_data-1})") + print( + f" X-check ancillas: {self.num_plaquettes} (IDs: {self.xcheck_qubits[0]}-{self.xcheck_qubits[-1]})" + ) + print( + f" Z-check ancillas: {self.num_plaquettes} (IDs: {self.zcheck_qubits[0]}-{self.zcheck_qubits[-1]})" + ) + print(f" Total qubits: {len(self.all_qubits)}") + print(f" Plaquettes: {len(self.plaquettes)}") + print() + + # Print grid layout + print("Data qubit grid (user coordinates):") + for row_idx in range(self.n_rows): + row = -row_idx + width = self._get_row_width(row_idx) + start_col = self._get_row_start_col(width) + + qubits_str = [] + for i in range(width): + col = start_col + i + if (row, col) in self.coord_to_qubit: + qid = self.coord_to_qubit[(row, col)] + qubits_str.append(f"D{qid:2d}") + + indent = " " * (self.n_cols // 2 - (-start_col)) + print(f" row {row:3d}: {indent}{' '.join(qubits_str)}") + print() + + # Print CNN grid + print("CNN grid layout (0-indexed, -1 = padding):") + grid = self.get_grid_array() + print(" " + " ".join(f"c{c}" for c in range(self.n_cols))) + for r in range(self.n_rows): + row_str = " ".join(f"{grid[r,c]:3d}" if grid[r, c] >= 0 else " ." + for c in range(self.n_cols)) + print(f" row {r}: {row_str}") + print() + + # Print plaquettes with syndrome mapping + print( + "Plaquettes (sorted by grid position, top-to-bottom, left-to-right):" + ) + boundary_count = bulk_count = 0 + for i, plaq in enumerate(self.plaquettes): + if plaq['type'] == 'boundary': + boundary_count += 1 + else: + bulk_count += 1 + grid_pos = plaq['grid_pos'] + print( + f" Plaq {i:2d} (X:{plaq['x_ancilla']:2d}, Z:{plaq['z_ancilla']:2d}, {plaq['color']:5s}, " + f"{plaq['type']:8s}, w{plaq['weight']}): " + f"{plaq['data_qubits']} -> D{plaq['mapped_qubit']} @ grid({grid_pos[0]},{grid_pos[1]})" + ) + print( + f"\nSummary: {boundary_count} boundary + {bulk_count} bulk = {len(self.plaquettes)} plaquettes" + ) + print() + + # ---------------------------------------------------------------------------------- + # Circuit-only physical layout (rectangular grid with blanks, including ancillas) + # ---------------------------------------------------------------------------------- + def get_circuit_physical_layout( + self, + *, + id_order: str = "rtl", + flip_rows: bool = False) -> Dict[int, Tuple[int, int]]: + """ + Return a *circuit-only* physical layout mapping qubit_id -> (r, c) on a rectangular grid. + + This layout is meant ONLY for reasoning about 2D nearest-neighbor connectivity constraints during + circuit construction. It does not affect the existing coordinate systems used elsewhere: + - `qubit_to_coord` / `coord_to_qubit` (triangular user coords) + - `qubit_to_grid` / `grid_to_qubit` (CNN rectangular embedding) + + Layout rules (as provided by user, generalized for odd distance d): + - Number of rows equals `self.n_rows = d + (d-1)//2`. + - Row lengths follow: 1, 3, 4, 5, 7, 8, 9, 11, 12, 13, ... (increments 2,1,1 repeating). + - Within each row, tokens alternate between data sites (D) and ancilla pairs (X,Z), and the X/Z + ancillas are adjacent horizontally with Z immediately to the left of X (left-to-right: Z then X). + - Row start offsets create a triangular envelope; the resulting rectangular width is (2*d - 1). + + Mapping convention: + - Data sites are assigned ids 0..num_data-1 using a deterministic per-row order controlled by `id_order`. + - Ancillas are assigned ids in two global blocks (all X first, then all Z), and within each block we also + use `id_order` per row. + - NOTE: Even though physically we place Z before X in each row, we still assign X ids first globally. + + Args: + id_order: + - "rtl": assign ids within each row from right-to-left. This matches the legacy triangle's upside-down + convention and makes the legacy schedule nearest-neighbor on this grid for odd distances tested. + - "ltr": assign ids within each row from left-to-right (natural scan order). + flip_rows: + - If True, return coordinates after reflecting the row index: (r, c) -> (n_rows - 1 - r, c). + This is useful when you want the same schedule embedded onto an up-facing vs down-facing triangle. + """ + d = int(self.distance) + width = 2 * d - 1 + n_rows = int(self.n_rows) + if id_order not in ("rtl", "ltr"): + raise ValueError("id_order must be 'rtl' or 'ltr'") + + # Row lengths: 1, 3, 4, 5, 7, 8, 9, 11, ... + def row_len(row_idx: int) -> int: + if row_idx == 0: + return 1 + g = row_idx // 3 + pos = row_idx % 3 + # pos 0: +1 from previous end of triple => 2g+5 for g>=1 (works out from pattern) + # easiest: build from recurrence: L0=1; delta pattern [2,1,1] repeating. + # but closed form below matches the observed sequence: + if pos == 0: + return 2 * g + 5 + if pos == 1: + return 2 * g + 3 + # pos == 2 + return 2 * g + 4 + + # More robust: generate lengths by recurrence to avoid mistakes. + lengths = [1] + deltas = [2, 1, 1] + for i in range(1, n_rows): + lengths.append(lengths[-1] + deltas[(i - 1) % 3]) + + # Row start offsets (column indices in [-d+1, d-1]) + starts = [0] + for i in range(1, n_rows): + # first delta=2 and first delta=1 both shift start left by 1; second delta=1 keeps start + starts.append(starts[-1] + (-1 if (i - 1) % 3 in (0, 1) else 0)) + + # Token generators per row type (Z then X) + def tokens_for_row(row_idx: int, L: int) -> List[str]: + if row_idx == 0: + return ["D"] + pos = row_idx % 3 + out: List[str] = [] + if pos == 0: + # start with "DD" + out.extend(["D", "D"]) + elif pos == 1: + # start with "D" + out.append("D") + else: # pos == 2 + # start with "ZX" + out.extend(["Z", "X"]) + + # Alternate between ZX and DD blocks. + # Determine next block type based on what we ended with. + next_block = "ZX" if (len(out) > 0 and out[-1] == "D") else "DD" + while len(out) < L: + if next_block == "ZX": + out.extend(["Z", "X"]) + next_block = "DD" + else: + out.extend(["D", "D"]) + next_block = "ZX" + return out[:L] + + # Collect token coordinates; assign ids afterward using `id_order`. + layout: Dict[int, Tuple[int, int]] = {} + d_positions: List[Tuple[int, int]] = [] + x_positions: List[Tuple[int, int]] = [] + z_positions: List[Tuple[int, int]] = [] + + for r in range(n_rows): + L = lengths[r] + start = starts[r] + toks = tokens_for_row(r, L) + for j, tok in enumerate(toks): + col = start + j + # shift to [0..width-1] + c = col + (d - 1) + if not (0 <= c < width): + raise AssertionError( + f"Physical layout column out of range: row={r} col={col} width={width}" + ) + if tok == "D": + d_positions.append((r, c)) + elif tok == "X": + x_positions.append((r, c)) + elif tok == "Z": + z_positions.append((r, c)) + else: + raise AssertionError(f"Unknown token {tok}") + + if len(d_positions) != int(self.num_data): + raise AssertionError( + f"Expected exactly num_data={self.num_data} data sites in physical layout, got {len(d_positions)}" + ) + + def _row_sort_key(rc: Tuple[int, int]) -> Tuple[int, int]: + rr, cc = rc + return (rr, -cc) if id_order == "rtl" else (rr, cc) + + # Assign data ids + data_id = 0 + for rc in sorted(d_positions, key=_row_sort_key): + layout[data_id] = rc + data_id += 1 + + # Assign ancilla ids: X first globally, then Z (regardless of left-to-right placement). + if len(x_positions) != int( + self.num_plaquettes) or len(z_positions) != int( + self.num_plaquettes): + raise AssertionError( + f"Expected exactly num_plaquettes={self.num_plaquettes} X and Z ancillas in physical layout, " + f"got X={len(x_positions)} Z={len(z_positions)}") + + x_id = int(self.num_data) + for (r, c) in sorted(x_positions, key=_row_sort_key): + layout[x_id] = (r, c) + x_id += 1 + + z_id = int(self.num_data + self.num_plaquettes) + for (r, c) in sorted(z_positions, key=_row_sort_key): + layout[z_id] = (r, c) + z_id += 1 + + if data_id != int(self.num_data) or x_id != int( + self.num_data + + self.num_plaquettes) or z_id != int(self.num_data + + 2 * self.num_plaquettes): + raise AssertionError( + "Physical layout did not assign all qubits: " + f"data={data_id}/{self.num_data} x={x_id - self.num_data}/{self.num_plaquettes} z={z_id - (self.num_data + self.num_plaquettes)}/{self.num_plaquettes}" + ) + + if flip_rows: + H = n_rows + return {q: (H - 1 - rc[0], rc[1]) for q, rc in layout.items()} + return layout + + def superdense_plaquette(self, plaq_idx: int) -> Dict[str, int]: + """ + Return a canonical labeling for a plaquette for the superdense circuit. + + Labels follow the convention discussed in chat: + - a1: X-ancilla (prepared in |+>, measured in X) + - a2: Z-ancilla (prepared in |0>, measured in Z) + - q1..q6: data qubits ordered by compass position around the plaquette (for weight-6): + q1 = NW, q2 = W, q3 = SW, q4 = NE, q5 = E, q6 = SE + + Weight-6 plaquettes occupy a 3x2 block in (row, col) coordinates. + + Weight-4 plaquettes are embedded into the same frame by populating only: + - q1, q2 (feed into a1 via the q*->a1 half) + - q5, q6 (feed into a2 via the q*->a2 half) + and setting q3 and q4 to -1 (missing). This matches using the same global 8-step schedule, + while weight-4 plaquettes naturally skip the third pair steps. + """ + if plaq_idx < 0 or plaq_idx >= len(self.plaquettes): + raise IndexError(f"plaq_idx out of range: {plaq_idx}") + + plaq = self.plaquettes[plaq_idx] + w = int(plaq["weight"]) + if w not in (4, 6): + raise ValueError( + f"Unsupported plaquette weight={w} for plaq_idx={plaq_idx}") + + data = list(plaq["data_qubits"]) + coords = {q: self.qubit_to_coord[q] for q in data} # (row, col) + + rows = sorted({r for r, _ in coords.values()}, + reverse=True) # top (largest) -> bottom (smallest) + cols = sorted({c for _, c in coords.values()}) # left -> right + + out: Dict[str, int] = { + "a1": int(plaq["x_ancilla"]), + "a2": int(plaq["z_ancilla"]), + } + + coord_to_qid = {v: k for k, v in coords.items()} + + if w == 6: + if len(rows) != 3 or len(cols) != 2: + raise ValueError( + "Expected weight-6 plaquette data qubits to occupy exactly 3 distinct rows and 2 distinct cols " + f"but got rows={rows}, cols={cols} for plaq_idx={plaq_idx}, data_qubits={data}, coords={coords}" + ) + + row_top, row_mid, row_bot = rows + col_left, col_right = cols + + # West column (left): q1 (NW), q2 (W), q3 (SW) + # East column (right): q4 (NE), q5 (E), q6 (SE) + expected_positions = { + "q1": (row_top, col_left), + "q2": (row_mid, col_left), + "q3": (row_bot, col_left), + "q4": (row_top, col_right), + "q5": (row_mid, col_right), + "q6": (row_bot, col_right), + } + + missing = [] + for label, pos in expected_positions.items(): + qid = coord_to_qid.get(pos) + if qid is None: + missing.append((label, pos)) + else: + out[label] = int(qid) + + if missing: + raise ValueError( + f"Could not assign all q1..q6 labels for plaq_idx={plaq_idx}; missing={missing}; " + f"data_qubits={data}; coords={coords}") + return out + + # --- weight-4 embedding into q1/q2/q5/q6; q3/q4 are missing --- + out["q3"] = -1 + out["q4"] = -1 + + # Case A: South boundary 2x2 block (two rows, two cols) + if len(rows) == 2 and len(cols) == 2: + row_top, row_bot = rows # already sorted top->bottom + col_left, col_right = cols + + # User-confirmed for south boundary: + # q1 = NW (top-left), q2 = W (bottom-left), q3 = NE (top-right), q4 = E (bottom-right). + # We embed into the w6 schedule by mapping: + # q1 -> q1, q2 -> q2, q3 -> q5, q4 -> q6 (and q3/q4 are the unused w6 labels). + pos_q1 = (row_top, col_left) + pos_q2 = (row_bot, col_left) + pos_q5 = (row_top, col_right) # NE + pos_q6 = (row_bot, col_right) # E / SE + + for key, pos in [("q1", pos_q1), ("q2", pos_q2), ("q5", pos_q5), + ("q6", pos_q6)]: + qid = coord_to_qid.get(pos) + if qid is None: + raise ValueError( + f"Missing expected {key} position {pos} for w4 2x2 plaq_idx={plaq_idx}, coords={coords}" + ) + out[key] = int(qid) + return out + + # Case B: L-shape boundary (three rows, two cols, four points). + # Empirically in this construction, one column has 3 qubits (dense) and the other has 1 (sparse), + # with the sparse qubit on the bottom row. + if len(rows) == 3 and len(cols) == 2: + col_a, col_b = cols + pts_a = [q for q, (r, c) in coords.items() if c == col_a] + pts_b = [q for q, (r, c) in coords.items() if c == col_b] + + if len(pts_a) == 3 and len(pts_b) == 1: + dense_col, sparse_col = col_a, col_b + elif len(pts_b) == 3 and len(pts_a) == 1: + dense_col, sparse_col = col_b, col_a + else: + raise ValueError( + f"Unexpected w4 L-shape column counts for plaq_idx={plaq_idx}: cols={cols}, counts={[len(pts_a), len(pts_b)]}, coords={coords}" + ) + + row_top, row_mid, row_bot = rows + + # Use dense column for q1/q2 (feeding a1), and use (sparse bottom, dense bottom) + # for q5/q6 (feeding a2). This uses all 4 data qubits and is consistent across boundary types. + pos_q1 = (row_top, dense_col) + pos_q2 = (row_mid, dense_col) + pos_q5 = (row_bot, sparse_col) + pos_q6 = (row_bot, dense_col) + + for key, pos in [("q1", pos_q1), ("q2", pos_q2), ("q5", pos_q5), + ("q6", pos_q6)]: + qid = coord_to_qid.get(pos) + if qid is None: + raise ValueError( + f"Missing expected {key} position {pos} for w4 L-shape plaq_idx={plaq_idx}, coords={coords}" + ) + out[key] = int(qid) + return out + + raise ValueError( + f"Unsupported w4 geometry for plaq_idx={plaq_idx}: distinct_rows={len(rows)}, distinct_cols={len(cols)}, coords={coords}" + ) + + return out + + +# --------------------------------------------------------------------------- +# CUDA-QX plugin glue: Pauli words over the data qubits +# --------------------------------------------------------------------------- + + +def _plaquette_pauli_words( + grid: "ColorCodeGeometry") -> Tuple[List[str], List[str]]: + """Return (x_words, z_words): one pure-X and one pure-Z Pauli word per + plaquette, over the data qubits, in plaquette (grid-sorted) order. + + The code is a self-dual CSS code: the X and Z stabilizers of a plaquette + share the same support, so both words are derived from the same + ``data_qubits`` list. Word index 0 is data qubit 0 (CUDA-QX convention: + leftmost Pauli character acts on qubit 0). + """ + x_words: List[str] = [] + z_words: List[str] = [] + for plaq in grid.plaquettes: + chars = ['I'] * grid.num_data + for q in plaq['data_qubits']: + chars[q] = 'X' + x_words.append(''.join(chars)) + chars = ['I'] * grid.num_data + for q in plaq['data_qubits']: + chars[q] = 'Z' + z_words.append(''.join(chars)) + return x_words, z_words + + +def _logical_pauli_words(grid: "ColorCodeGeometry") -> Tuple[str, str]: + """Return (x_word, z_word) for the logical X/Z operators. + + Both logicals use the bottom-edge representative (``logical_qubits``, + weight exactly d) — see ColorCodeGeometry._find_logical_qubits for why + the bottom edge is preferred over the full data-qubit support. + """ + chars = ['I'] * grid.num_data + for q in grid.logical_qubits: + chars[q] = 'X' + x_word = ''.join(chars) + return x_word, x_word.replace('X', 'Z') + + +# --------------------------------------------------------------------------- +# CUDA-Q kernels +# +# These operate on the framework `patch` type (data / ancx / ancz qubit +# views). The memory-circuit driver (libs/qec/lib/device/memory_circuit.cpp) +# wraps stabilizer_round with cudaq::detector / cudaq::detectors / +# cudaq::logical_observable annotations, so DEM extraction and +# detector-ordered sampling need no extra work here. +# --------------------------------------------------------------------------- + + +@cudaq.kernel +def prep0(logicalQubit: patch): + # Transversal |0...0> prep; the first stabilizer round projects into the + # codespace with deterministic Z stabilizers. + reset(logicalQubit.data) + + +@cudaq.kernel +def prep1(logicalQubit: patch): + # X on every data qubit is a logical-X representative: every plaquette + # has even weight (4 or 6) so it commutes with all Z stabilizers, and it + # flips the weight-d (odd) bottom-edge logical Z. + prep0(logicalQubit) + x(logicalQubit.data) + + +@cudaq.kernel +def prepp(logicalQubit: patch): + # The code is self-dual CSS (identical X/Z supports), so transversal H + # preserves the stabilizer group and maps logical |0> to |+>. + prep0(logicalQubit) + h(logicalQubit.data) + + +@cudaq.kernel +def prepm(logicalQubit: patch): + prep0(logicalQubit) + x(logicalQubit.data) + h(logicalQubit.data) + + +@cudaq.kernel +def stabilizer_round(logicalQubit: patch, x_stabilizers: list[int], + z_stabilizers: list[int]) -> list[cudaq.measure_handle]: + # x_stabilizers / z_stabilizers are the flattened + # [num_stabilizers x num_data] parity rows handed over by the framework + # (row i, column q at index i * num_data + q). + num_data = len(logicalQubit.data) + + # X-stabilizer half: ancilla in |+>, CX from ancilla onto plaquette data. + h(logicalQubit.ancx) + for xi in range(len(logicalQubit.ancx)): + for di in range(num_data): + if x_stabilizers[xi * num_data + di] == 1: + x.ctrl(logicalQubit.ancx[xi], logicalQubit.data[di]) + h(logicalQubit.ancx) + + # Z-stabilizer half: CX from plaquette data onto ancilla. + for zi in range(len(logicalQubit.ancz)): + for di in range(num_data): + if z_stabilizers[zi * num_data + di] == 1: + x.ctrl(logicalQubit.data[di], logicalQubit.ancz[zi]) + + # [Z][X] measurement order matches the framework's per-round detector + # layout. + results = mz([*logicalQubit.ancz, *logicalQubit.ancx]) + + reset(logicalQubit.ancx) + reset(logicalQubit.ancz) + return results + + +# --------------------------------------------------------------------------- +# Plugin registration +# --------------------------------------------------------------------------- + + +@qec.code('color_code') +class ColorCode: + """Triangular color code plugin for CUDA-QX. + + One ancilla per stabilizer per basis: with P = 3(d^2-1)/8 plaquettes the + patch holds (3d^2+1)/4 data qubits plus P X-ancillas and P Z-ancillas. + ``distance`` (odd, >= 3) must be provided via + ``qec.get_code('color_code', distance=d)``. + + The full grid geometry (plaquette layout, syndrome-to-grid mapping, CNN + embedding, physical circuit layout) is exposed on the ``grid`` attribute, + an instance of :class:`ColorCodeGeometry`. + """ + + def __init__(self, **kwargs): + # The Code binding accepts no constructor arguments; kwargs from + # qec.get_code(...) are consumed here on the Python side. + qec.Code.__init__(self) + if 'distance' not in kwargs: + raise RuntimeError( + "[color_code] distance not provided. distance must be " + "provided via qec.get_code('color_code', distance=d).") + self.distance = kwargs['distance'] + self.grid = ColorCodeGeometry(self.distance) + + x_words, z_words = _plaquette_pauli_words(self.grid) + self.stabilizers = [ + cudaq.SpinOperator.from_word(w) for w in z_words + x_words + ] + obs_x, obs_z = _logical_pauli_words(self.grid) + self.pauli_observables = [ + cudaq.SpinOperator.from_word(w) for w in (obs_x, obs_z) + ] + + self.operation_encodings = { + qec.operation.prep0: prep0, + qec.operation.prep1: prep1, + qec.operation.prepp: prepp, + qec.operation.prepm: prepm, + qec.operation.stabilizer_round: stabilizer_round, + } + + def get_num_data_qubits(self): + return self.grid.num_data + + def get_num_ancilla_x_qubits(self): + return self.grid.num_plaquettes + + def get_num_ancilla_z_qubits(self): + return self.grid.num_plaquettes + + def get_num_ancilla_qubits(self): + return 2 * self.grid.num_plaquettes + + def get_num_x_stabilizers(self): + return self.grid.num_plaquettes + + def get_num_z_stabilizers(self): + return self.grid.num_plaquettes + + +# --------------------------------------------------------------------------- +# Superdense memory circuit +# +# Superdense memory circuit for the triangular color code. +# +# Each plaquette measures both its X and Z stabilizer in one round using a +# paired ancilla: the X-ancilla is prepared in |+>, the Z-ancilla in |0>, and +# an 8-CNOT-layer schedule entangles the pair (layers 1 and 8), couples each +# plaquette's data qubits into the pair with data as control (layers 2-4), and +# mirrors those couplings with the ancillas as control (layers 5-7). The +# mirrored half applies, per plaquette, an X on the data qubits coupled to the +# Z-ancilla conditioned on that ancilla's state; rather than measuring +# mid-circuit and feeding forward, the detectors carry the feedback-inlined +# parities, so the circuit stays straight-line Clifford. +# +# Label space used by this module: with N data qubits and P plaquettes, +# data qubits are 0..N-1, N + i is the X-ancilla of plaquette i, and +# N + P + i is the Z-ancilla of plaquette i (plaquette index order of +# :class:`ColorCodeGeometry`). +# +# Entry points: :func:`superdense_dem` (detector error model) and +# :func:`superdense_sample` (detector-ordered syndromes, final data readout, +# and logical parity). Both drive the :func:`superdense_memory` kernel, whose +# detector/observable annotations are emitted from a +# :class:`SuperdensePlan` — the host-side source of truth for the record +# layout, the per-detector measurement sets, and the detector coordinates. +# +# Decoder integration: `cudaq.detector` carries no coordinates, so the DEM +# returned by :func:`superdense_dem` is coordinate-free. +# ``SuperdensePlan(distance, rounds, basis).detector_coords`` supplies the +# 4-tuple ``(grid_row, grid_col, t, c)`` for each detector row, in emission +# order, with ``c = color + 3*basis`` (red/green/blue = 0/1/2; +3 for +# Z-checks) — the annotation convention Chromobius expects for color-code +# decoding. +# --------------------------------------------------------------------------- + + +def _rowmajor_cnot_layers(d: int) -> list[list[tuple[int, int]]]: + """ + The 8 CNOT layers of the superdense schedule in row-major inverted-triangle + numbering. + + The triangle is oriented with its widest row (d data qubits) on top, + narrowing to a single qubit at the bottom. + + Returns: + layers: length-8 list; each element is a list of (control, target) + pairs where + - data qubits: 0..num_data-1, row-major top-to-bottom + - ancillas: num_data..num_data+2*num_plaquettes-1, grouped as + (a1, a2) = (num_data + 2p, num_data + 2p + 1) with a1 the + X-ancilla and a2 the Z-ancilla of plaquette p + """ + d = int(d) + num_data = (3 * d * d + 1) // 4 + num_plaquettes = (3 * (d * d - 1)) // 8 + num_rows_data_qubits = (3 * d - 1) // 2 + + layers: list[list[tuple[int, int]]] = [] + + # tt=1..8 correspond to 8 layers + for tt in range(1, 9): + edges: list[tuple[int, int]] = [] + + if tt == 1 or tt == 8: + # CNOT between the two ancilla qubits: control |+> (a1), target |0> (a2) + index = num_data + for _ in range(num_plaquettes): + a1 = index + a2 = index + 1 + edges.append((a1, a2)) + index += 2 + + elif tt == 2: + # First sequence (data = control) + data_qubit_index = d + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + elif tt == 3: + # Second sequence (data = control) + data_qubit_index = 0 + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + elif tt == 4: + # Third sequence (data = control) + data_qubit_index = 1 + index_ancilla = num_data + d - 1 + cols = d - 1 + for rr in range(num_rows_data_qubits - 2): + if rr % 3 == 0: + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + elif rr % 3 == 1: + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 2 + else: # rr % 3 == 2 + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + + elif tt == 5: + # First sequence (data = target) => ancilla is control + data_qubit_index = d + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + elif tt == 6: + # Second sequence (data = target) => ancilla is control + data_qubit_index = 0 + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + else: # tt == 7 + # Third sequence (data = target) => ancilla is control + data_qubit_index = 1 + index_ancilla = num_data + d - 1 + cols = d - 1 + for rr in range(num_rows_data_qubits - 2): + if rr % 3 == 0: + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + elif rr % 3 == 1: + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 2 + else: # rr % 3 == 2 + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + + layers.append(sorted(edges)) + + return layers + + +def _rowmajor_to_unified(grid: ColorCodeGeometry) -> dict[int, int]: + """ + Bijection from the row-major inverted-triangle qubit numbering of + :func:`_rowmajor_cnot_layers` to the unified label space. + + Data qubits: the grid's coordinates put row 0 at the top with rows + decreasing (more negative) downward, so sorting data ids by (row, col) + ascending enumerates them bottom-to-top, left-to-right — exactly the + row-major order of the inverted triangle (widest row first). + + Ancillas: plaquettes are matched by their data-qubit support sets (the + data endpoints coupled to an ancilla pair across all layers), then + (a1, a2) = (num_data + 2p, num_data + 2p + 1) maps to + (N + i, N + P + i) for the matching plaquette index i. + """ + N = int(grid.num_data) + P = int(grid.num_plaquettes) + + ordered_data = sorted( + range(N), + key=lambda q: (grid.qubit_to_coord[q][0], grid.qubit_to_coord[q][1])) + data_to_rowmajor = {q: i for i, q in enumerate(ordered_data)} + + layers = _rowmajor_cnot_layers(grid.distance) + + # Support set (in row-major data ids) of each row-major plaquette. + support_to_plaq = {} + for p in range(P): + a1 = N + 2 * p + a2 = N + 2 * p + 1 + ds = set() + for layer in layers: + for c, t in layer: + if c < N and t in (a1, a2): + ds.add(c) + if c in (a1, a2) and t < N: + ds.add(t) + support_to_plaq[tuple(sorted(ds))] = p + + mapping = {i: q for q, i in data_to_rowmajor.items()} + for i, plaq in enumerate(grid.plaquettes): + key = tuple(sorted(data_to_rowmajor[q] for q in plaq['data_qubits'])) + p = support_to_plaq.get(key) + if p is None: + raise ValueError( + f"Plaquette {i} (data qubits {plaq['data_qubits']}) has no " + f"support-set match in the schedule") + mapping[N + 2 * p] = N + i + mapping[N + 2 * p + 1] = N + P + i + return mapping + + +def superdense_cnot_layers( + grid: ColorCodeGeometry) -> list[list[tuple[int, int]]]: + """Eight CNOT layers of the paired-ancilla superdense schedule. + + Unified label space: 0..N-1 data qubit ids, N+i the X-ancilla and + N+P+i the Z-ancilla of plaquette i. Layers 1 and 8 entangle each + plaquette's ancilla pair; layers 2-4 couple data (control) into the + pair; layers 5-7 apply the mirrored ancilla-controlled CNOTs. + """ + mapping = _rowmajor_to_unified(grid) + return [ + sorted((mapping[c], mapping[t]) + for c, t in layer) + for layer in _rowmajor_cnot_layers(grid.distance) + ] + + +def z_side_data(grid: ColorCodeGeometry) -> list[list[int]]: + """Per plaquette, the data qubits coupled to its Z-ancilla by the + schedule; a conditional X on exactly these qubits is the byproduct the + Z-ancilla readout heralds.""" + layers = superdense_cnot_layers(grid) + N, P = grid.num_data, grid.num_plaquettes + out = [set() for _ in range(P)] + for li in (1, 2, 3): + for c, t in layers[li]: + if t >= N + P: + out[t - N - P].add(c) + return [sorted(s) for s in out] + + +_COLOR_IDX = {'red': 0, 'green': 1, 'blue': 2} + + +class SuperdensePlan: + """Detector/observable layout of the superdense memory circuit. + + Record indexing: round r contributes records [2*P*r, 2*P*r + P) for the + Z-ancillas (plaquette order) then [2*P*r + P, 2*P*(r+1)) for the + X-ancillas; the final transversal data measurement occupies + [2*P*rounds, 2*P*rounds + N) in data-qubit order. + + The Z-ancilla readouts herald conditional-X byproducts on their + schedule-side data qubits; detectors and the Z-basis observable carry + the absorbed correction records instead of physical feedback gates. + """ + + def __init__(self, distance, rounds, basis): + if basis not in ('X', 'Z'): + raise ValueError("basis must be 'X' or 'Z'") + if rounds < 2: + raise ValueError("rounds must be >= 2") + self.grid = ColorCodeGeometry(distance) + self.rounds = rounds + self.basis = basis + grid = self.grid + P, N = grid.num_plaquettes, grid.num_data + self.num_records = 2 * P * rounds + N + + zside = z_side_data(grid) + + def F(support): + s = set(support) + return [a for a in range(P) if len(set(zside[a]) & s) % 2 == 1] + + self.prev_sets = [ + sorted({p} ^ set(F(grid.plaquettes[p]['data_qubits']))) + for p in range(P) + ] + self.obs_plaqs = sorted(F(grid.logical_qubits)) + + Z = lambda p, r: 2 * P * r + p + X = lambda p, r: 2 * P * r + P + p + D = lambda q: 2 * P * rounds + q + + def coords(p, t, z_type): + gp = grid.plaquettes[p]['grid_pos'] + c = _COLOR_IDX[grid.plaquettes[p]['color']] + (3 if z_type else 0) + return (float(gp[0]), float(gp[1]), float(t), float(c)) + + dets, cs = [], [] + for p in range(P): + if basis == 'Z': + dets.append(frozenset({Z(p, 0)})) + cs.append(coords(p, 0, True)) + else: + dets.append(frozenset({X(p, 0)})) + cs.append(coords(p, 0, False)) + for r in range(1, rounds): + for p in range(P): + dets.append(frozenset({X(p, r), X(p, r - 1)})) + cs.append(coords(p, 0, False)) + for p in range(P): + dets.append( + frozenset({Z(p, r)}) | + {Z(a, r - 1) for a in self.prev_sets[p]}) + cs.append(coords(p, 0, True)) + for p in range(P): + supp = grid.plaquettes[p]['data_qubits'] + if basis == 'Z': + dets.append( + frozenset(D(q) for q in supp) | + {Z(a, rounds - 1) for a in self.prev_sets[p]}) + cs.append(coords(p, 1, True)) + else: + dets.append( + frozenset({X(p, rounds - 1)}) | {D(q) for q in supp}) + cs.append(coords(p, 1, False)) + self.detectors = dets + self.detector_coords = cs + + if basis == 'Z': + obs = {D(q) for q in grid.logical_qubits} + for r in range(rounds): + obs ^= {Z(a, r) for a in self.obs_plaqs} + self.observable = frozenset(obs) + else: + self.observable = frozenset(D(q) for q in range(N)) + + def detector_bits(self, measurements): + m = np.asarray(measurements, dtype=np.uint8) + out = np.zeros((m.shape[0], len(self.detectors)), dtype=np.uint8) + for j, s in enumerate(self.detectors): + out[:, j] = np.bitwise_xor.reduce(m[:, sorted(s)], axis=1) + return out + + def observable_bits(self, measurements): + m = np.asarray(measurements, dtype=np.uint8) + return np.bitwise_xor.reduce(m[:, sorted(self.observable)], axis=1) + + +def _kernel_args(plan, p_cx): + if p_cx < 0: + raise ValueError(f"p_cx must be non-negative, got {p_cx}") + grid = plan.grid + N, P, R = grid.num_data, grid.num_plaquettes, plan.rounds + layers = superdense_cnot_layers(grid) + sched = [q for layer in layers for e in layer for q in e] + sched_off = [0] + for layer in layers: + sched_off.append(sched_off[-1] + 2 * len(layer)) + # prev_sets and final supports, padded to fixed strides + ps_stride = max(len(s) for s in plan.prev_sets) + ps_flat, ps_cnt = [], [] + for s in plan.prev_sets: + ps_cnt.append(len(s)) + ps_flat.extend(s + [0] * (ps_stride - len(s))) + supp_stride = 6 + supp_flat, supp_cnt = [], [] + for p in range(P): + supp = grid.plaquettes[p]['data_qubits'] + supp_cnt.append(len(supp)) + supp_flat.extend(list(supp) + [0] * (supp_stride - len(supp))) + obs = sorted(plan.obs_plaqs) + logical = list(grid.logical_qubits) + return (N, P, R, 1 if plan.basis == 'Z' else 0, float(p_cx), sched, + sched_off, ps_flat, ps_cnt, ps_stride, supp_flat, supp_cnt, + supp_stride, obs, logical) + + +@cudaq.kernel +def superdense_memory(N: int, P: int, R: int, z_basis: int, p_cx: float, + sched: list[int], sched_off: list[int], + ps_flat: list[int], ps_cnt: list[int], ps_stride: int, + supp_flat: list[int], supp_cnt: list[int], + supp_stride: int, obs: list[int], logical: list[int]): + # One register indexed directly by the unified labels: q[0..N) data, + # q[N..N+P) X-ancillas, q[N+P..N+2P) Z-ancillas (plaquette order), so + # the sched entries need no decoding. Per round the Z-ancillas are + # measured before the X-ancillas and the final data measurement comes + # last: exactly the SuperdensePlan record layout. + q = cudaq.qvector(N + 2 * P) + + if z_basis == 0: + for i in range(N): + h(q[i]) + + # Round 0. Fresh qubits start in |0>, so the per-round ancilla resets + # are elided; only the X-ancilla |+> prep is needed. + for i in range(P): + h(q[N + i]) + for li in range(8): + for k in range(sched_off[li], sched_off[li + 1], 2): + x.ctrl(q[sched[k]], q[sched[k + 1]]) + # Perfect-final-round convention: noise on every schedule CX of + # every round except the last. + if p_cx > 0.0 and R > 1: + cudaq.apply_noise(cudaq.Depolarization2, p_cx, q[sched[k]], + q[sched[k + 1]]) + zprev = mz(q[N + P:N + 2 * P]) + if z_basis == 1: + # Z-basis observable: the obs_plaqs Z-ancilla records of every + # round accumulate into L0 (inlined feed-forward byproduct). + for j in range(len(obs)): + cudaq.logical_observable(zprev[obs[j]]) + for i in range(P): + h(q[N + i]) + xprev = mz(q[N:N + P]) + # Round-0 detectors: memory-basis single-record checks. + if z_basis == 1: + for p in range(P): + cudaq.detector(zprev[p]) + else: + for p in range(P): + cudaq.detector(xprev[p]) + + for r in range(1, R): + for i in range(P): + reset(q[N + i]) + h(q[N + i]) + reset(q[N + P + i]) + for li in range(8): + for k in range(sched_off[li], sched_off[li + 1], 2): + x.ctrl(q[sched[k]], q[sched[k + 1]]) + if p_cx > 0.0 and r < R - 1: + cudaq.apply_noise(cudaq.Depolarization2, p_cx, q[sched[k]], + q[sched[k + 1]]) + zcurr = mz(q[N + P:N + 2 * P]) + if z_basis == 1: + for j in range(len(obs)): + cudaq.logical_observable(zcurr[obs[j]]) + for i in range(P): + h(q[N + i]) + xcurr = mz(q[N:N + P]) + for p in range(P): + cudaq.detector(xcurr[p], xprev[p]) + for p in range(P): + # Z comparison detector: current Z record against the previous + # round's prev_set records (plaquette indices into zprev). + if ps_cnt[p] == 0: + cudaq.detector(zcurr[p]) + else: + psel = [ + zprev[ps_flat[p * ps_stride + j]] for j in range(ps_cnt[p]) + ] + cudaq.detector(zcurr[p], psel) + zprev = zcurr + xprev = xcurr + + if z_basis == 0: + for i in range(N): + h(q[i]) + dm = mz(q[0:N]) + for p in range(P): + dsel = [dm[supp_flat[p * supp_stride + j]] for j in range(supp_cnt[p])] + if z_basis == 1: + if ps_cnt[p] == 0: + cudaq.detector(dsel) + else: + psel = [ + zprev[ps_flat[p * ps_stride + j]] for j in range(ps_cnt[p]) + ] + cudaq.detector(dsel, psel) + else: + cudaq.detector(xprev[p], dsel) + if z_basis == 1: + for j in range(len(logical)): + cudaq.logical_observable(dm[logical[j]]) + else: + cudaq.logical_observable(dm) + + +def superdense_dem(distance, rounds, basis, p_cx): + """Detector error model of the superdense memory circuit. + + The returned model's detector rows follow the plan's emission order; + chromobius coordinates for each row are available from + SuperdensePlan(distance, rounds, basis).detector_coords. + """ + plan = SuperdensePlan(distance, rounds, basis) + # An (empty) noise model must be passed or in-kernel apply_noise is a + # silent no-op and the DEM comes back with zero error mechanisms. + text = cudaq.dem_from_kernel(superdense_memory, + *_kernel_args(plan, p_cx), + noise_model=cudaq.NoiseModel()) + return qec.dem_from_stim_text(text) + + +def superdense_sample(distance, rounds, basis, p_cx, shots): + """Sample the superdense memory circuit. + + Returns: + (syndromes, data, logical): syndromes is a (shots, 2*P*rounds) uint8 + array of detector bits in plan emission order; data is a (shots, N) + array of raw final data-qubit bits; logical is a (shots,) array of + observable parity. + """ + plan = SuperdensePlan(distance, rounds, basis) + # Same activation requirement as in superdense_dem: without a noise + # model argument the in-kernel apply_noise calls do nothing. + res = cudaq.sample(superdense_memory, + *_kernel_args(plan, p_cx), + shots_count=shots, + explicit_measurements=True, + noise_model=cudaq.NoiseModel()) + # get_sequential_data() yields one '0'/'1' string per shot in record + # order; convert per character (np.array on the raw strings would parse + # each whole string as a single number). + m = np.array([[c == '1' for c in s] for s in res.get_sequential_data()], + dtype=np.uint8) + if m.shape[1] != plan.num_records: + raise RuntimeError( + f"expected {plan.num_records} measurement records per shot, " + f"got {m.shape[1]}") + N = plan.grid.num_data + return (plan.detector_bits(m), m[:, -N:], plan.observable_bits(m)) + + +if __name__ == "__main__": + for d in [3, 5, 7]: + print("=" * 60) + c = ColorCodeGeometry(d) + c.print_structure() diff --git a/libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem b/libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem new file mode 100644 index 000000000..1cf14cf76 --- /dev/null +++ b/libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem @@ -0,0 +1,334 @@ +# Reference superdense color-code DEM, d=3, 3 rounds, DEPOLARIZE2(0.01) per CX, perfect final round. +error(0.001338700097173320998) D0 D1 D2 D6 D7 D8 L0 +error(0.0006697986788568588423) D0 D1 D2 D6 D7 L0 +error(0.0006697986788568588423) D0 D1 D2 D6 L0 +error(0.001338700097173320998) D0 D1 D2 D7 D8 L0 +error(0.0006697986788568588423) D0 D1 D2 D7 L0 +error(0.002673815958446297981) D0 D1 D2 D8 L0 +error(0.003340032800510209492) D0 D1 D2 L0 +error(0.002006705456917235505) D0 D1 D4 +error(0.002006705456917235505) D0 D1 D4 D7 +error(0.0006697986788568588423) D0 D1 D4 D7 D8 +error(0.0006697986788568588423) D0 D1 D4 D8 +error(0.001338700097173320998) D0 D1 D5 D6 D7 D8 L0 +error(0.0006697986788568588423) D0 D1 D5 D6 D7 L0 +error(0.0006697986788568588423) D0 D1 D5 D6 L0 +error(0.0006697986788568588423) D0 D1 D5 D7 D8 L0 +error(0.0006697986788568588423) D0 D1 D5 D8 L0 +error(0.001338700097173320998) D0 D1 D5 L0 +error(0.001338700097173320998) D0 D1 D6 D7 L0 +error(0.001338700097173320998) D0 D1 D6 L0 +error(0.002673815958446297981) D0 D1 D7 L0 +error(0.002673815958446297981) D0 D1 L0 +error(0.002006705456917235505) D0 D2 D3 +error(0.002006705456917235505) D0 D2 D3 D6 +error(0.0006697986788568588423) D0 D2 D3 D6 D7 +error(0.0006697986788568588423) D0 D2 D3 D7 +error(0.005333333333333313206) D0 D2 D5 +error(0.005333333333333313206) D0 D2 D5 D8 +error(0.001338700097173320998) D0 D2 D6 D8 L0 +error(0.001338700097173320998) D0 D2 D6 L0 +error(0.002673815958446297981) D0 D2 D8 L0 +error(0.002673815958446297981) D0 D2 L0 +error(0.007978628588222850399) D0 D3 +error(0.003340032800510209492) D0 D3 D6 +error(0.002006705456917235505) D0 D3 D6 D7 +error(0.001338700097173320998) D0 D3 D6 D7 D8 +error(0.001338700097173320998) D0 D3 D6 D8 +error(0.0006697986788568588423) D0 D3 D7 D8 +error(0.004669790293214320931) D0 D3 D8 +error(0.001338700097173320998) D0 D4 D5 D6 D7 D8 L0 +error(0.0006697986788568588423) D0 D4 D5 D6 D7 L0 +error(0.0006697986788568588423) D0 D4 D5 D6 L0 +error(0.0006697986788568588423) D0 D4 D5 D7 D8 L0 +error(0.0006697986788568588423) D0 D4 D5 D8 L0 +error(0.001338700097173320998) D0 D4 D5 L0 +error(0.002006705456917235505) D0 D4 D6 D7 L0 +error(0.0006697986788568588423) D0 D4 D6 L0 +error(0.0006697986788568588423) D0 D4 D7 L0 +error(0.002006705456917235505) D0 D4 L0 +error(0.001338700097173320998) D0 D5 D6 D8 L0 +error(0.001338700097173320998) D0 D5 D6 L0 +error(0.001338700097173320998) D0 D5 D8 L0 +error(0.001338700097173320998) D0 D5 L0 +error(0.002673815958446297981) D0 D6 L0 +error(0.002673815958446297981) D0 L0 +error(0.0006697986788568588423) D1 D2 D3 D6 D7 D8 L0 +error(0.0006697986788568588423) D1 D2 D3 D6 D7 L0 +error(0.001338700097173320998) D1 D2 D3 D6 L0 +error(0.0006697986788568588423) D1 D2 D3 D7 D8 L0 +error(0.0006697986788568588423) D1 D2 D3 D7 L0 +error(0.001338700097173320998) D1 D2 D3 L0 +error(0.0006697986788568588423) D1 D2 D6 D7 L0 +error(0.0006697986788568588423) D1 D2 D6 D8 L0 +error(0.001338700097173320998) D1 D2 D7 D8 L0 +error(0.0006697986788568588423) D1 D2 D7 L0 +error(0.002006705456917235505) D1 D2 D8 L0 +error(0.002673815958446297981) D1 D2 L0 +error(0.01126536362635755656) D1 D4 +error(0.001338700097173320998) D1 D4 D6 +error(0.0006697986788568588423) D1 D4 D6 D7 +error(0.0006697986788568588423) D1 D4 D6 D7 D8 +error(0.004005357180252827609) D1 D4 D7 +error(0.002673815958446297981) D1 D4 D7 D8 +error(0.0006697986788568588423) D1 D4 D8 +error(0.0006697986788568588423) D1 D5 D6 D7 L0 +error(0.0006697986788568588423) D1 D5 D6 D8 L0 +error(0.002006705456917235505) D1 D5 D7 D8 L0 +error(0.002673815958446297981) D1 D5 D8 L0 +error(0.004669790293214320931) D1 D5 L0 +error(0.002673815958446297981) D1 D7 L0 +error(0.002673815958446297981) D1 L0 +error(0.0006697986788568588423) D2 D3 D6 D8 L0 +error(0.004669790293214320931) D2 D3 D6 L0 +error(0.0006697986788568588423) D2 D3 D8 L0 +error(0.004669790293214320931) D2 D3 L0 +error(0.001338700097173320998) D2 D4 D7 D8 L0 +error(0.001338700097173320998) D2 D4 D7 L0 +error(0.001338700097173320998) D2 D4 D8 L0 +error(0.001338700097173320998) D2 D4 L0 +error(0.007978628588222850399) D2 D5 +error(0.001338700097173320998) D2 D5 D6 +error(0.001338700097173320998) D2 D5 D6 D7 +error(0.0006697986788568588423) D2 D5 D6 D7 D8 +error(0.004669790293214320931) D2 D5 D6 D8 +error(0.0006697986788568588423) D2 D5 D7 D8 +error(0.004669790293214320931) D2 D5 D8 +error(0.0006697986788568588423) D2 D6 D8 L0 +error(0.0006697986788568588423) D2 D6 L0 +error(0.002006705456917235505) D2 D8 L0 +error(0.002006705456917235505) D2 L0 +error(0.001338700097173320998) D3 D4 D5 D6 D7 D8 L0 +error(0.001338700097173320998) D3 D4 D5 D6 D7 D14 L0 +error(0.0006697986788568588423) D3 D4 D5 D6 D7 L0 +error(0.0006697986788568588423) D3 D4 D5 D6 D12 L0 +error(0.001338700097173320998) D3 D4 D5 D6 D13 D14 L0 +error(0.0006697986788568588423) D3 D4 D5 D7 D13 L0 +error(0.0006697986788568588423) D3 D4 D5 D8 D12 D13 L0 +error(0.001338700097173320998) D3 D4 D5 D8 D14 L0 +error(0.0006697986788568588423) D3 D4 D5 D8 L0 +error(0.001338700097173320998) D3 D4 D5 D12 D13 D14 L0 +error(0.003340032800510209492) D3 D4 D5 L0 +error(0.0006697986788568588423) D3 D4 D6 D7 D10 +error(0.0006697986788568588423) D3 D4 D6 D7 D10 D14 +error(0.002006705456917235505) D3 D4 D6 D7 L0 +error(0.0006697986788568588423) D3 D4 D6 D10 D13 +error(0.0006697986788568588423) D3 D4 D6 D10 D13 D14 +error(0.0006697986788568588423) D3 D4 D6 D12 L0 +error(0.001338700097173320998) D3 D4 D6 D13 L0 +error(0.001338700097173320998) D3 D4 D7 D10 D13 +error(0.0006697986788568588423) D3 D4 D7 D11 D12 L0 +error(0.0006697986788568588423) D3 D4 D7 D11 D13 D14 L0 +error(0.0006697986788568588423) D3 D4 D7 D12 L0 +error(0.001338700097173320998) D3 D4 D7 D13 L0 +error(0.0006697986788568588423) D3 D4 D8 D11 D12 D13 L0 +error(0.0006697986788568588423) D3 D4 D8 D11 D14 L0 +error(0.001338700097173320998) D3 D4 D10 +error(0.001338700097173320998) D3 D4 D11 D12 D13 D14 L0 +error(0.001338700097173320998) D3 D4 D11 L0 +error(0.001338700097173320998) D3 D4 D12 D13 L0 +error(0.003340032800510209492) D3 D4 L0 +error(0.0006697986788568588423) D3 D5 D6 D7 D8 D11 +error(0.0006697986788568588423) D3 D5 D6 D7 D11 D14 +error(0.0006697986788568588423) D3 D5 D6 D8 D11 +error(0.001338700097173320998) D3 D5 D6 D8 L0 +error(0.0006697986788568588423) D3 D5 D6 D9 +error(0.001338700097173320998) D3 D5 D6 D9 D12 +error(0.0006697986788568588423) D3 D5 D6 D9 D13 +error(0.0006697986788568588423) D3 D5 D6 D11 D14 +error(0.0006697986788568588423) D3 D5 D6 D12 L0 +error(0.001338700097173320998) D3 D5 D6 D14 L0 +error(0.0006697986788568588423) D3 D5 D6 L0 +error(0.004005357180252827609) D3 D5 D8 D11 D14 +error(0.0006697986788568588423) D3 D5 D8 D12 L0 +error(0.001338700097173320998) D3 D5 D8 D14 L0 +error(0.0006697986788568588423) D3 D5 D8 L0 +error(0.001338700097173320998) D3 D5 D9 +error(0.0006697986788568588423) D3 D5 D9 D12 +error(0.0006697986788568588423) D3 D5 D9 D12 D13 +error(0.004005357180252827609) D3 D5 D11 +error(0.001338700097173320998) D3 D5 D12 D14 L0 +error(0.002673815958446297981) D3 D5 L0 +error(0.001338700097173320998) D3 D6 D9 +error(0.002673815958446297981) D3 D6 D9 D12 +error(0.001338700097173320998) D3 D6 D9 D12 D13 +error(0.0006697986788568588423) D3 D6 D9 D13 D14 +error(0.004669790293214320931) D3 D6 D9 D14 +error(0.0006697986788568588423) D3 D6 D10 D11 D12 D13 L0 +error(0.0006697986788568588423) D3 D6 D10 D11 D14 L0 +error(0.0006697986788568588423) D3 D6 D10 D12 D13 L0 +error(0.0006697986788568588423) D3 D6 D10 L0 +error(0.0006697986788568588423) D3 D6 D11 D12 L0 +error(0.0006697986788568588423) D3 D6 D11 D14 L0 +error(0.001338700097173320998) D3 D6 D12 L0 +error(0.002673815958446297981) D3 D6 L0 +error(0.0006697986788568588423) D3 D7 D10 D11 D12 L0 +error(0.0006697986788568588423) D3 D7 D10 D11 D13 D14 L0 +error(0.0006697986788568588423) D3 D7 D10 D12 L0 +error(0.0006697986788568588423) D3 D7 D10 D13 L0 +error(0.0006697986788568588423) D3 D8 D11 D12 L0 +error(0.0006697986788568588423) D3 D8 D11 D14 L0 +error(0.006657753962803452177) D3 D9 +error(0.0006697986788568588423) D3 D9 D12 +error(0.0006697986788568588423) D3 D9 D12 D13 +error(0.001338700097173320998) D3 D9 D12 D13 D14 +error(0.001338700097173320998) D3 D9 D12 D14 +error(0.001338700097173320998) D3 D10 D11 D12 D13 D14 L0 +error(0.001338700097173320998) D3 D10 D11 L0 +error(0.001338700097173320998) D3 D10 D12 D13 L0 +error(0.001338700097173320998) D3 D10 L0 +error(0.001338700097173320998) D3 D11 D12 D14 L0 +error(0.001338700097173320998) D3 D11 L0 +error(0.001338700097173320998) D3 D12 L0 +error(0.002673815958446297981) D3 L0 +error(0.001338700097173320998) D4 D5 D6 D9 D12 L0 +error(0.0006697986788568588423) D4 D5 D6 D9 D13 D14 L0 +error(0.0006697986788568588423) D4 D5 D6 D9 D13 L0 +error(0.002006705456917235505) D4 D5 D7 D8 L0 +error(0.0006697986788568588423) D4 D5 D7 D13 L0 +error(0.001338700097173320998) D4 D5 D7 D14 L0 +error(0.0006697986788568588423) D4 D5 D8 D12 D13 L0 +error(0.0006697986788568588423) D4 D5 D8 D12 D14 L0 +error(0.0006697986788568588423) D4 D5 D8 D14 L0 +error(0.0006697986788568588423) D4 D5 D9 D12 D13 D14 L0 +error(0.0006697986788568588423) D4 D5 D9 D12 D13 L0 +error(0.001338700097173320998) D4 D5 D9 L0 +error(0.001338700097173320998) D4 D5 D13 D14 L0 +error(0.003340032800510209492) D4 D5 L0 +error(0.0006697986788568588423) D4 D6 D7 D8 D11 L0 +error(0.0006697986788568588423) D4 D6 D7 D11 D14 L0 +error(0.0006697986788568588423) D4 D7 D8 D11 L0 +error(0.004669790293214320931) D4 D7 D10 +error(0.001338700097173320998) D4 D7 D10 D12 +error(0.002673815958446297981) D4 D7 D10 D13 +error(0.001338700097173320998) D4 D7 D10 D13 D14 +error(0.0006697986788568588423) D4 D7 D10 D14 +error(0.0006697986788568588423) D4 D7 D11 D13 D14 L0 +error(0.0006697986788568588423) D4 D7 D11 D14 L0 +error(0.0006697986788568588423) D4 D7 D11 L0 +error(0.001338700097173320998) D4 D7 D13 L0 +error(0.007978628588222850399) D4 D7 L0 +error(0.0006697986788568588423) D4 D8 D11 D12 D13 L0 +error(0.0006697986788568588423) D4 D8 D11 D12 D14 L0 +error(0.001338700097173320998) D4 D8 D11 D14 L0 +error(0.006657753962803452177) D4 D10 +error(0.0006697986788568588423) D4 D10 D12 D13 +error(0.0006697986788568588423) D4 D10 D12 D13 D14 +error(0.001338700097173320998) D4 D10 D13 +error(0.001338700097173320998) D4 D10 D13 D14 +error(0.001338700097173320998) D4 D11 D13 D14 L0 +error(0.002673815958446297981) D4 D11 L0 +error(0.001338700097173320998) D4 D13 L0 +error(0.007978628588222850399) D4 L0 +error(0.0006697986788568588423) D5 D6 D7 D10 D14 L0 +error(0.0006697986788568588423) D5 D6 D8 L0 +error(0.004005357180252827609) D5 D6 D9 D12 L0 +error(0.0006697986788568588423) D5 D6 D9 D14 L0 +error(0.0006697986788568588423) D5 D6 D9 L0 +error(0.0006697986788568588423) D5 D6 D10 D13 D14 L0 +error(0.0006697986788568588423) D5 D6 L0 +error(0.0006697986788568588423) D5 D7 D8 D11 +error(0.001338700097173320998) D5 D7 D10 D13 L0 +error(0.0006697986788568588423) D5 D7 D10 D14 L0 +error(0.0006697986788568588423) D5 D7 D11 D14 +error(0.0006697986788568588423) D5 D8 D11 +error(0.001338700097173320998) D5 D8 D11 D12 +error(0.001338700097173320998) D5 D8 D11 D12 D13 +error(0.004005357180252827609) D5 D8 D11 D12 D14 +error(0.002673815958446297981) D5 D8 D11 D14 +error(0.0006697986788568588423) D5 D8 D12 D14 L0 +error(0.0006697986788568588423) D5 D8 D12 L0 +error(0.0006697986788568588423) D5 D8 D14 L0 +error(0.004005357180252827609) D5 D8 L0 +error(0.0006697986788568588423) D5 D9 D12 D14 L0 +error(0.0006697986788568588423) D5 D9 D12 L0 +error(0.004005357180252827609) D5 D9 L0 +error(0.0006697986788568588423) D5 D10 D13 D14 L0 +error(0.001338700097173320998) D5 D10 L0 +error(0.006657753962803452177) D5 D11 +error(0.0006697986788568588423) D5 D11 D12 D13 D14 +error(0.0006697986788568588423) D5 D11 D12 D14 +error(0.0006697986788568588423) D5 D11 D13 D14 +error(0.001338700097173320998) D5 D11 D14 +error(0.001338700097173320998) D5 D14 L0 +error(0.004669790293214320931) D5 L0 +error(0.01257390183676828158) D6 +error(0.005333333333333313206) D6 D7 +error(0.003340032800510209492) D6 D7 D8 +error(0.0006697986788568588423) D6 D7 D10 L0 +error(0.001338700097173320998) D6 D7 D14 +error(0.006657753962803452177) D6 D8 +error(0.0006697986788568588423) D6 D8 D11 L0 +error(0.0006697986788568588423) D6 D9 D10 D11 D12 D13 L0 +error(0.0006697986788568588423) D6 D9 D10 D11 D14 L0 +error(0.0006697986788568588423) D6 D9 D10 D12 D13 L0 +error(0.0006697986788568588423) D6 D9 D10 L0 +error(0.0006697986788568588423) D6 D9 D11 D12 L0 +error(0.0006697986788568588423) D6 D9 D11 D14 L0 +error(0.0006697986788568588423) D6 D9 D12 L0 +error(0.0006697986788568588423) D6 D9 L0 +error(0.0006697986788568588423) D6 D10 D13 L0 +error(0.0006697986788568588423) D6 D11 D14 L0 +error(0.006657753962803452177) D6 D12 +error(0.001338700097173320998) D6 D12 D13 +error(0.001338700097173320998) D6 D13 +error(0.001338700097173320998) D6 D13 D14 +error(0.005333333333333313206) D6 D14 +error(0.01387893656672014447) D7 +error(0.005333333333333313206) D7 D8 +error(0.0006697986788568588423) D7 D10 D11 D13 D14 L0 +error(0.0006697986788568588423) D7 D10 D11 L0 +error(0.004669790293214320931) D7 D10 D13 L0 +error(0.001338700097173320998) D7 D10 L0 +error(0.001338700097173320998) D7 D12 +error(0.006657753962803452177) D7 D13 +error(0.001338700097173320998) D7 D13 D14 +error(0.001338700097173320998) D7 D14 +error(0.01647853308100971984) D8 +error(0.0006697986788568588423) D8 D11 D12 D14 L0 +error(0.0006697986788568588423) D8 D11 D12 L0 +error(0.001338700097173320998) D8 D11 D14 L0 +error(0.0006697986788568588423) D8 D11 L0 +error(0.001338700097173320998) D8 D12 +error(0.001338700097173320998) D8 D12 D13 +error(0.004005357180252827609) D8 D12 D14 +error(0.006657753962803452177) D8 D14 +error(0.0006697986788568588423) D9 D10 D11 D12 D13 D14 L0 +error(0.0006697986788568588423) D9 D10 D11 L0 +error(0.0006697986788568588423) D9 D10 D12 D13 L0 +error(0.0006697986788568588423) D9 D10 L0 +error(0.0006697986788568588423) D9 D11 D12 D14 L0 +error(0.0006697986788568588423) D9 D11 L0 +error(0.0006697986788568588423) D9 D12 L0 +error(0.0006697986788568588423) D9 L0 +error(0.0006697986788568588423) D10 D11 D13 D14 L0 +error(0.0006697986788568588423) D10 D11 L0 +error(0.001338700097173320998) D10 D13 L0 +error(0.004669790293214320931) D10 L0 +error(0.001338700097173320998) D11 D14 L0 +error(0.002006705456917235505) D11 L0 +error(0.001338700097173320998) D12 +error(0.002006705456917235505) D12 D13 +error(0.002673815958446297981) D12 D13 D14 +error(0.002006705456917235505) D12 D14 +error(0.001338700097173320998) D13 +error(0.002006705456917235505) D13 D14 +error(0.001338700097173320998) D14 +detector(0, 1, 0, 1) D0 +detector(1, 1, 0, 0) D1 +detector(2, 1, 0, 2) D2 +detector(0, 1, 0, 1) D3 +detector(1, 1, 0, 0) D4 +detector(2, 1, 0, 2) D5 +detector(0, 1, 0, 4) D6 +detector(1, 1, 0, 3) D7 +detector(2, 1, 0, 5) D8 +detector(0, 1, 0, 1) D9 +detector(1, 1, 0, 0) D10 +detector(2, 1, 0, 2) D11 +detector(0, 1, 0, 4) D12 +detector(1, 1, 0, 3) D13 +detector(2, 1, 0, 5) D14 +detector(0, 1, 1, 1) D15 +detector(1, 1, 1, 0) D16 +detector(2, 1, 1, 2) D17 diff --git a/libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem b/libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem new file mode 100644 index 000000000..e6928b85e --- /dev/null +++ b/libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem @@ -0,0 +1,303 @@ +# Reference superdense color-code DEM, d=3, 3 rounds, DEPOLARIZE2(0.01) per CX, perfect final round. +error(0.003340032800510209492) D0 +error(0.001338700097173320998) D0 D1 +error(0.001338700097173320998) D0 D1 D2 +error(0.001338700097173320998) D0 D1 D2 D5 +error(0.001338700097173320998) D0 D1 D4 +error(0.001338700097173320998) D0 D1 D4 D8 +error(0.001338700097173320998) D0 D1 D5 D8 +error(0.002673815958446297981) D0 D1 D8 +error(0.001338700097173320998) D0 D2 +error(0.001338700097173320998) D0 D2 D5 +error(0.003340032800510209492) D0 D3 +error(0.0006697986788568588423) D0 D3 D4 +error(0.0006697986788568588423) D0 D3 D4 D5 D6 D7 +error(0.0006697986788568588423) D0 D3 D4 D5 D8 +error(0.0006697986788568588423) D0 D3 D4 D6 D7 +error(0.0006697986788568588423) D0 D3 D5 D6 +error(0.0006697986788568588423) D0 D3 D5 D8 +error(0.009953312530086681764) D0 D3 D6 +error(0.001338700097173320998) D0 D3 D6 D7 +error(0.001338700097173320998) D0 D3 D7 +error(0.001338700097173320998) D0 D3 D7 D8 +error(0.005333333333333313206) D0 D3 D8 +error(0.0006697986788568588423) D0 D4 +error(0.0006697986788568588423) D0 D4 D5 D6 D7 +error(0.0006697986788568588423) D0 D4 D5 D8 +error(0.0006697986788568588423) D0 D4 D6 D7 +error(0.001338700097173320998) D0 D4 D7 +error(0.001338700097173320998) D0 D4 D7 D8 +error(0.0006697986788568588423) D0 D5 D6 +error(0.002006705456917235505) D0 D5 D8 +error(0.009953312530086681764) D0 D6 +error(0.001338700097173320998) D0 D6 D7 +error(0.002673815958446297981) D0 D7 +error(0.002673815958446297981) D0 D7 D8 +error(0.006657753962803452177) D0 D8 +error(0.001338700097173320998) D1 D2 D5 L0 +error(0.001338700097173320998) D1 D2 L0 +error(0.0006697986788568588423) D1 D4 D5 D6 +error(0.001338700097173320998) D1 D4 D5 D7 D8 +error(0.0006697986788568588423) D1 D4 D5 L0 +error(0.002006705456917235505) D1 D4 D6 +error(0.01060977777777773884) D1 D4 D7 +error(0.001338700097173320998) D1 D4 D7 D8 +error(0.001338700097173320998) D1 D4 D8 L0 +error(0.005995987492949031786) D1 D4 L0 +error(0.0006697986788568588423) D1 D5 D6 +error(0.001338700097173320998) D1 D5 D7 D8 +error(0.001338700097173320998) D1 D5 D8 L0 +error(0.0006697986788568588423) D1 D5 L0 +error(0.002006705456917235505) D1 D6 +error(0.01060977777777773884) D1 D7 +error(0.001338700097173320998) D1 D7 D8 +error(0.002673815958446297981) D1 D8 L0 +error(0.005995987492949031786) D1 L0 +error(0.002673815958446297981) D2 D5 D6 +error(0.002673815958446297981) D2 D5 D6 D7 +error(0.005333333333333313206) D2 D5 D6 D8 L0 +error(0.01060977777777773884) D2 D5 D8 +error(0.001338700097173320998) D2 D5 L0 +error(0.002673815958446297981) D2 D6 +error(0.002673815958446297981) D2 D6 D7 +error(0.005333333333333313206) D2 D6 D8 L0 +error(0.01060977777777773884) D2 D8 +error(0.001338700097173320998) D2 L0 +error(0.01518047719643240284) D3 +error(0.002673815958446297981) D3 D4 +error(0.003340032800510209492) D3 D4 D5 +error(0.001338700097173320998) D3 D4 D5 D6 D7 D8 +error(0.001338700097173320998) D3 D4 D5 D6 D7 D14 +error(0.0006697986788568588423) D3 D4 D5 D6 D12 +error(0.001338700097173320998) D3 D4 D5 D6 D13 D14 +error(0.0006697986788568588423) D3 D4 D5 D7 D13 +error(0.0006697986788568588423) D3 D4 D5 D8 D12 D13 +error(0.001338700097173320998) D3 D4 D5 D8 D14 +error(0.001338700097173320998) D3 D4 D5 D12 D13 D14 +error(0.001338700097173320998) D3 D4 D6 D7 +error(0.0006697986788568588423) D3 D4 D6 D7 D10 +error(0.0006697986788568588423) D3 D4 D6 D7 D10 D14 +error(0.0006697986788568588423) D3 D4 D6 D10 D13 +error(0.0006697986788568588423) D3 D4 D6 D10 D13 D14 +error(0.0006697986788568588423) D3 D4 D6 D12 +error(0.001338700097173320998) D3 D4 D6 D13 +error(0.001338700097173320998) D3 D4 D7 D10 D13 +error(0.0006697986788568588423) D3 D4 D7 D11 D12 +error(0.0006697986788568588423) D3 D4 D7 D11 D13 D14 +error(0.0006697986788568588423) D3 D4 D7 D12 +error(0.001338700097173320998) D3 D4 D7 D13 +error(0.0006697986788568588423) D3 D4 D8 D11 D12 D13 +error(0.0006697986788568588423) D3 D4 D8 D11 D14 +error(0.001338700097173320998) D3 D4 D10 +error(0.001338700097173320998) D3 D4 D11 +error(0.001338700097173320998) D3 D4 D11 D12 D13 D14 +error(0.001338700097173320998) D3 D4 D12 D13 +error(0.002673815958446297981) D3 D5 +error(0.0006697986788568588423) D3 D5 D6 D7 D8 D11 +error(0.0006697986788568588423) D3 D5 D6 D7 D11 D14 +error(0.001338700097173320998) D3 D5 D6 D8 +error(0.0006697986788568588423) D3 D5 D6 D8 D11 +error(0.0006697986788568588423) D3 D5 D6 D9 +error(0.001338700097173320998) D3 D5 D6 D9 D12 +error(0.0006697986788568588423) D3 D5 D6 D9 D13 +error(0.0006697986788568588423) D3 D5 D6 D11 D14 +error(0.0006697986788568588423) D3 D5 D6 D12 +error(0.001338700097173320998) D3 D5 D6 D14 +error(0.004005357180252827609) D3 D5 D8 D11 D14 +error(0.0006697986788568588423) D3 D5 D8 D12 +error(0.001338700097173320998) D3 D5 D8 D14 +error(0.001338700097173320998) D3 D5 D9 +error(0.0006697986788568588423) D3 D5 D9 D12 +error(0.0006697986788568588423) D3 D5 D9 D12 D13 +error(0.004005357180252827609) D3 D5 D11 +error(0.001338700097173320998) D3 D5 D12 D14 +error(0.004005357180252827609) D3 D6 +error(0.002006705456917235505) D3 D6 D7 +error(0.002006705456917235505) D3 D6 D7 D8 +error(0.002006705456917235505) D3 D6 D8 +error(0.001338700097173320998) D3 D6 D9 +error(0.002673815958446297981) D3 D6 D9 D12 +error(0.001338700097173320998) D3 D6 D9 D12 D13 +error(0.0006697986788568588423) D3 D6 D9 D13 D14 +error(0.004669790293214320931) D3 D6 D9 D14 +error(0.0006697986788568588423) D3 D6 D10 +error(0.0006697986788568588423) D3 D6 D10 D11 D12 D13 +error(0.0006697986788568588423) D3 D6 D10 D11 D14 +error(0.0006697986788568588423) D3 D6 D10 D12 D13 +error(0.0006697986788568588423) D3 D6 D11 D12 +error(0.0006697986788568588423) D3 D6 D11 D14 +error(0.001338700097173320998) D3 D6 D12 +error(0.0006697986788568588423) D3 D7 D10 D11 D12 +error(0.0006697986788568588423) D3 D7 D10 D11 D13 D14 +error(0.0006697986788568588423) D3 D7 D10 D12 +error(0.0006697986788568588423) D3 D7 D10 D13 +error(0.0006697986788568588423) D3 D8 D11 D12 +error(0.0006697986788568588423) D3 D8 D11 D14 +error(0.006657753962803452177) D3 D9 +error(0.0006697986788568588423) D3 D9 D12 +error(0.0006697986788568588423) D3 D9 D12 D13 +error(0.001338700097173320998) D3 D9 D12 D13 D14 +error(0.001338700097173320998) D3 D9 D12 D14 +error(0.001338700097173320998) D3 D10 +error(0.001338700097173320998) D3 D10 D11 +error(0.001338700097173320998) D3 D10 D11 D12 D13 D14 +error(0.001338700097173320998) D3 D10 D12 D13 +error(0.001338700097173320998) D3 D11 +error(0.001338700097173320998) D3 D11 D12 D14 +error(0.001338700097173320998) D3 D12 +error(0.01647853308100971984) D4 +error(0.004005357180252827609) D4 D5 +error(0.001338700097173320998) D4 D5 D6 D7 D8 +error(0.001338700097173320998) D4 D5 D6 D9 D12 +error(0.0006697986788568588423) D4 D5 D6 D9 D13 +error(0.0006697986788568588423) D4 D5 D6 D9 D13 D14 +error(0.001338700097173320998) D4 D5 D7 D8 L0 +error(0.0006697986788568588423) D4 D5 D7 D13 +error(0.001338700097173320998) D4 D5 D7 D14 L0 +error(0.0006697986788568588423) D4 D5 D8 D12 D13 +error(0.0006697986788568588423) D4 D5 D8 D12 D14 L0 +error(0.0006697986788568588423) D4 D5 D8 D14 +error(0.001338700097173320998) D4 D5 D9 +error(0.0006697986788568588423) D4 D5 D9 D12 D13 +error(0.0006697986788568588423) D4 D5 D9 D12 D13 D14 +error(0.001338700097173320998) D4 D5 D13 D14 L0 +error(0.002006705456917235505) D4 D6 D7 +error(0.0006697986788568588423) D4 D6 D7 D8 +error(0.0006697986788568588423) D4 D6 D7 D8 D11 +error(0.0006697986788568588423) D4 D6 D7 D11 D14 +error(0.0006697986788568588423) D4 D7 D8 D11 L0 +error(0.002006705456917235505) D4 D7 D8 L0 +error(0.001338700097173320998) D4 D7 D10 D12 +error(0.002673815958446297981) D4 D7 D10 D13 +error(0.001338700097173320998) D4 D7 D10 D13 D14 +error(0.0006697986788568588423) D4 D7 D10 D14 L0 +error(0.004669790293214320931) D4 D7 D10 L0 +error(0.0006697986788568588423) D4 D7 D11 D13 D14 +error(0.0006697986788568588423) D4 D7 D11 D14 L0 +error(0.0006697986788568588423) D4 D7 D11 L0 +error(0.001338700097173320998) D4 D7 D13 +error(0.004005357180252827609) D4 D7 L0 +error(0.0006697986788568588423) D4 D8 D11 D12 D13 +error(0.0006697986788568588423) D4 D8 D11 D12 D14 L0 +error(0.001338700097173320998) D4 D8 D11 D14 +error(0.006657753962803452177) D4 D10 +error(0.0006697986788568588423) D4 D10 D12 D13 +error(0.0006697986788568588423) D4 D10 D12 D13 D14 +error(0.001338700097173320998) D4 D10 D13 D14 L0 +error(0.001338700097173320998) D4 D10 D13 L0 +error(0.002673815958446297981) D4 D11 +error(0.001338700097173320998) D4 D11 D13 D14 L0 +error(0.001338700097173320998) D4 D13 L0 +error(0.01906422791000844316) D5 +error(0.002006705456917235505) D5 D6 D7 D8 +error(0.0006697986788568588423) D5 D6 D7 D10 D14 +error(0.002006705456917235505) D5 D6 D8 +error(0.0006697986788568588423) D5 D6 D9 +error(0.004005357180252827609) D5 D6 D9 D12 +error(0.0006697986788568588423) D5 D6 D9 D14 +error(0.0006697986788568588423) D5 D6 D10 D13 D14 +error(0.0006697986788568588423) D5 D7 D8 D11 L0 +error(0.002006705456917235505) D5 D7 D8 L0 +error(0.001338700097173320998) D5 D7 D10 D13 +error(0.0006697986788568588423) D5 D7 D10 D14 L0 +error(0.0006697986788568588423) D5 D7 D11 D14 L0 +error(0.001338700097173320998) D5 D8 D11 D12 +error(0.001338700097173320998) D5 D8 D11 D12 D13 +error(0.004005357180252827609) D5 D8 D11 D12 D14 L0 +error(0.002673815958446297981) D5 D8 D11 D14 +error(0.0006697986788568588423) D5 D8 D11 L0 +error(0.0006697986788568588423) D5 D8 D12 +error(0.0006697986788568588423) D5 D8 D12 D14 L0 +error(0.0006697986788568588423) D5 D8 D14 +error(0.003340032800510209492) D5 D8 L0 +error(0.004005357180252827609) D5 D9 +error(0.0006697986788568588423) D5 D9 D12 +error(0.0006697986788568588423) D5 D9 D12 D14 +error(0.001338700097173320998) D5 D10 +error(0.0006697986788568588423) D5 D10 D13 D14 L0 +error(0.006657753962803452177) D5 D11 +error(0.0006697986788568588423) D5 D11 D12 D13 D14 +error(0.0006697986788568588423) D5 D11 D12 D14 +error(0.0006697986788568588423) D5 D11 D13 D14 L0 +error(0.001338700097173320998) D5 D11 D14 L0 +error(0.001338700097173320998) D5 D14 L0 +error(0.004669790293214320931) D6 +error(0.004005357180252827609) D6 D7 +error(0.004669790293214320931) D6 D7 D8 +error(0.0006697986788568588423) D6 D7 D10 +error(0.001338700097173320998) D6 D7 D14 +error(0.004005357180252827609) D6 D8 +error(0.0006697986788568588423) D6 D8 D11 +error(0.0006697986788568588423) D6 D9 +error(0.0006697986788568588423) D6 D9 D10 +error(0.0006697986788568588423) D6 D9 D10 D11 D12 D13 +error(0.0006697986788568588423) D6 D9 D10 D11 D14 +error(0.0006697986788568588423) D6 D9 D10 D12 D13 +error(0.0006697986788568588423) D6 D9 D11 D12 +error(0.0006697986788568588423) D6 D9 D11 D14 +error(0.0006697986788568588423) D6 D9 D12 +error(0.0006697986788568588423) D6 D10 D13 +error(0.0006697986788568588423) D6 D11 D14 +error(0.006657753962803452177) D6 D12 +error(0.001338700097173320998) D6 D12 D13 +error(0.001338700097173320998) D6 D13 +error(0.001338700097173320998) D6 D13 D14 +error(0.005333333333333313206) D6 D14 +error(0.004005357180252827609) D7 D8 L0 +error(0.0006697986788568588423) D7 D10 D11 D13 D14 +error(0.0006697986788568588423) D7 D10 D11 L0 +error(0.004669790293214320931) D7 D10 D13 +error(0.001338700097173320998) D7 D10 L0 +error(0.001338700097173320998) D7 D12 +error(0.006657753962803452177) D7 D13 +error(0.001338700097173320998) D7 D13 D14 +error(0.001338700097173320998) D7 D14 L0 +error(0.007318633932043431753) D7 L0 +error(0.0006697986788568588423) D8 D11 D12 +error(0.0006697986788568588423) D8 D11 D12 D14 L0 +error(0.001338700097173320998) D8 D11 D14 +error(0.0006697986788568588423) D8 D11 L0 +error(0.001338700097173320998) D8 D12 +error(0.001338700097173320998) D8 D12 D13 +error(0.004005357180252827609) D8 D12 D14 L0 +error(0.006657753962803452177) D8 D14 +error(0.003340032800510209492) D8 L0 +error(0.0006697986788568588423) D9 +error(0.0006697986788568588423) D9 D10 +error(0.0006697986788568588423) D9 D10 D11 +error(0.0006697986788568588423) D9 D10 D11 D12 D13 D14 +error(0.0006697986788568588423) D9 D10 D12 D13 +error(0.0006697986788568588423) D9 D11 +error(0.0006697986788568588423) D9 D11 D12 D14 +error(0.0006697986788568588423) D9 D12 +error(0.004669790293214320931) D10 +error(0.0006697986788568588423) D10 D11 +error(0.0006697986788568588423) D10 D11 D13 D14 L0 +error(0.001338700097173320998) D10 D13 L0 +error(0.002006705456917235505) D11 +error(0.001338700097173320998) D11 D14 L0 +error(0.001338700097173320998) D12 +error(0.002006705456917235505) D12 D13 +error(0.002673815958446297981) D12 D13 D14 +error(0.002006705456917235505) D12 D14 +error(0.002006705456917235505) D13 D14 L0 +error(0.001338700097173320998) D13 L0 +error(0.001338700097173320998) D14 L0 +detector(0, 1, 0, 4) D0 +detector(1, 1, 0, 3) D1 +detector(2, 1, 0, 5) D2 +detector(0, 1, 0, 1) D3 +detector(1, 1, 0, 0) D4 +detector(2, 1, 0, 2) D5 +detector(0, 1, 0, 4) D6 +detector(1, 1, 0, 3) D7 +detector(2, 1, 0, 5) D8 +detector(0, 1, 0, 1) D9 +detector(1, 1, 0, 0) D10 +detector(2, 1, 0, 2) D11 +detector(0, 1, 0, 4) D12 +detector(1, 1, 0, 3) D13 +detector(2, 1, 0, 5) D14 +detector(0, 1, 1, 4) D15 +detector(1, 1, 1, 3) D16 +detector(2, 1, 1, 5) D17 diff --git a/libs/qec/python/tests/test_color_code.py b/libs/qec/python/tests/test_color_code.py new file mode 100644 index 000000000..25e4c7b3f --- /dev/null +++ b/libs/qec/python/tests/test_color_code.py @@ -0,0 +1,650 @@ +# ============================================================================ # +# Copyright (c) 2026 NVIDIA Corporation & Affiliates. # +# All rights reserved. # +# # +# This source code and the accompanying materials are made available under # +# the terms of the Apache License 2.0 which accompanies this distribution. # +# ============================================================================ # +import pytest +import numpy as np +import cudaq +import cudaq_qec as qec + +import os + +from cudaq_qec.plugins.codes.color_code import ( + ColorCodeGeometry, SuperdensePlan, superdense_cnot_layers, z_side_data, + superdense_dem, superdense_sample, superdense_memory, _kernel_args) + + +@pytest.fixture(scope="module", autouse=True) +def set_target(): + cudaq.set_target("stim") + yield + cudaq.reset_target() + + +# Truth data transcribed from the source module docstring ("Reference +# plaquettes for verification"). Keyed by frozenset of data-qubit ids. +REFERENCE_PLAQUETTES = { + 3: { + frozenset([0, 1, 2, 3]): ('green', 'boundary'), + frozenset([2, 3, 4, 5]): ('blue', 'boundary'), + frozenset([1, 3, 5, 6]): ('red', 'boundary'), + }, + 5: { + frozenset([0, 1, 2, 3]): ('green', 'boundary'), + frozenset([2, 3, 4, 5, 7, 8]): ('blue', 'bulk'), + frozenset([1, 3, 5, 6]): ('red', 'boundary'), + frozenset([5, 6, 8, 9, 12, 13]): ('green', 'bulk'), + frozenset([7, 8, 11, 12, 15, 16]): ('red', 'bulk'), + frozenset([4, 7, 10, 11]): ('green', 'boundary'), + frozenset([10, 11, 14, 15]): ('blue', 'boundary'), + frozenset([12, 13, 16, 17]): ('blue', 'boundary'), + frozenset([9, 13, 17, 18]): ('red', 'boundary'), + }, + 7: { + frozenset([0, 1, 2, 3]): ('green', 'boundary'), + frozenset([2, 3, 4, 5, 7, 8]): ('blue', 'bulk'), + frozenset([1, 3, 5, 6]): ('red', 'boundary'), + frozenset([5, 6, 8, 9, 12, 13]): ('green', 'bulk'), + frozenset([7, 8, 11, 12, 15, 16]): ('red', 'bulk'), + frozenset([4, 7, 10, 11]): ('green', 'boundary'), + frozenset([10, 11, 14, 15, 19, 20]): ('blue', 'bulk'), + frozenset([12, 13, 16, 17, 21, 22]): ('blue', 'bulk'), + frozenset([9, 13, 17, 18]): ('red', 'boundary'), + frozenset([14, 19, 24, 25]): ('green', 'boundary'), + frozenset([15, 16, 20, 21, 26, 27]): ('green', 'bulk'), + frozenset([17, 18, 22, 23, 28, 29]): ('green', 'bulk'), + frozenset([19, 20, 25, 26, 31, 32]): ('red', 'bulk'), + frozenset([21, 22, 27, 28, 33, 34]): ('red', 'bulk'), + frozenset([23, 29, 35, 36]): ('red', 'boundary'), + frozenset([24, 25, 30, 31]): ('blue', 'boundary'), + frozenset([26, 27, 32, 33]): ('blue', 'boundary'), + frozenset([28, 29, 34, 35]): ('blue', 'boundary'), + }, +} + + +def support_matrix(grid): + """[num_plaquettes, num_data] 0/1 plaquette support matrix.""" + S = np.zeros((grid.num_plaquettes, grid.num_data), dtype=np.uint8) + for i, plaq in enumerate(grid.plaquettes): + S[i, plaq['data_qubits']] = 1 + return S + + +@pytest.mark.parametrize("d", [3, 5, 7, 9, 11, 13]) +def test_geometry_counts(d): + grid = ColorCodeGeometry(d) + assert grid.num_data == (3 * d * d + 1) // 4 + assert grid.num_plaquettes == (3 * (d * d - 1)) // 8 + assert grid.n_rows == d + (d - 1) // 2 + assert grid.n_cols == d + assert len(grid.plaquettes) == grid.num_plaquettes + assert len(grid.qubit_to_coord) == grid.num_data + assert len(grid.data_qubits) == grid.num_data + assert len(grid.xcheck_qubits) == grid.num_plaquettes + assert len(grid.zcheck_qubits) == grid.num_plaquettes + assert len(grid.all_qubits) == grid.num_data + 2 * grid.num_plaquettes + + +@pytest.mark.parametrize("d", [1, 2, 4, 6]) +def test_invalid_distance_rejected(d): + with pytest.raises(ValueError, match="odd"): + ColorCodeGeometry(d) + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_reference_plaquettes(d): + grid = ColorCodeGeometry(d) + actual = { + frozenset(p['data_qubits']): (p['color'], p['type']) + for p in grid.plaquettes + } + assert actual == REFERENCE_PLAQUETTES[d] + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_plaquettes_sorted_by_grid_position(d): + grid = ColorCodeGeometry(d) + positions = [p['grid_pos'] for p in grid.plaquettes] + assert positions == sorted(positions) + # Each syndrome maps to a distinct data-qubit grid cell (needed for the + # CNN grid embedding to be collision-free). + assert len(set(positions)) == len(positions) + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_syndrome_mapping_rule(d): + # Right boundary (red weight-4) maps to top-left; everything else to + # top-right (from the source module docstring). + grid = ColorCodeGeometry(d) + for i, plaq in enumerate(grid.plaquettes): + coords = [(q, grid.qubit_to_coord[q]) for q in plaq['data_qubits']] + top_row = max(c[0] for _, c in coords) + top = [(q, c) for q, c in coords if c[0] == top_row] + if plaq['color'] == 'red' and plaq['type'] == 'boundary': + expected = min(top, key=lambda x: x[1][1])[0] + else: + expected = max(top, key=lambda x: x[1][1])[0] + assert plaq['mapped_qubit'] == expected + assert grid.stab_to_data_idx[i] == expected + assert plaq['grid_pos'] == grid.qubit_to_grid[expected] + + +@pytest.mark.parametrize("d", [3, 5, 7, 9]) +def test_css_commutation(d): + # Self-dual CSS: X-stab i and Z-stab j commute iff their supports overlap + # on an even number of qubits. Since X and Z supports are identical + # plaquettes, check (S @ S.T) mod 2 == 0 (diagonal included: weights are + # 4 or 6, i.e. even). + grid = ColorCodeGeometry(d) + S = support_matrix(grid) + assert not ((S @ S.T) % 2).any() + + +@pytest.mark.parametrize("d", [3, 5, 7, 9]) +def test_logical_operator(d): + grid = ColorCodeGeometry(d) + # Bottom edge, weight exactly d. + assert len(grid.logical_qubits) == d + bottom_row = min(coord[0] for coord in grid.qubit_to_coord.values()) + assert all( + grid.qubit_to_coord[q][0] == bottom_row for q in grid.logical_qubits) + # Logical operator commutes with every stabilizer (even overlap with + # every plaquette). + S = support_matrix(grid) + L = np.zeros(grid.num_data, dtype=np.uint8) + L[grid.logical_qubits] = 1 + assert not ((S @ L) % 2).any() + + +def test_top_qubit_at_origin(): + # "Top qubit (qubit 0) is always at (row=0, col=0)" (module docstring). + for d in (3, 5, 7): + grid = ColorCodeGeometry(d) + assert grid.qubit_to_coord[0] == (0, 0) + + +# --------------------------------------------------------------------------- +# Layout helper methods +# --------------------------------------------------------------------------- + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_get_grid_array(d): + grid = ColorCodeGeometry(d) + arr = grid.get_grid_array() + assert arr.shape == (grid.n_rows, grid.n_cols) + non_pad = arr[arr >= 0] + assert sorted(non_pad.tolist()) == list(range(grid.num_data)) + for qid, (gr, gc) in grid.qubit_to_grid.items(): + assert arr[gr, gc] == qid + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_get_syndrome_grid_indices(d): + grid = ColorCodeGeometry(d) + idx = grid.get_syndrome_grid_indices() + assert idx.shape == (grid.num_plaquettes,) + for i, plaq in enumerate(grid.plaquettes): + gr, gc = plaq['grid_pos'] + assert idx[i] == gr * grid.n_cols + gc + # Distinct plaquettes map to distinct flat grid cells. + assert len(set(idx.tolist())) == len(idx) + + +@pytest.mark.parametrize("d", [3, 5, 7]) +@pytest.mark.parametrize("id_order", ["rtl", "ltr"]) +@pytest.mark.parametrize("flip_rows", [False, True]) +def test_circuit_physical_layout(d, id_order, flip_rows): + grid = ColorCodeGeometry(d) + layout = grid.get_circuit_physical_layout(id_order=id_order, + flip_rows=flip_rows) + n_total = grid.num_data + 2 * grid.num_plaquettes + # Every qubit id placed exactly once, on distinct sites, inside the + # (n_rows) x (2d-1) rectangle. + assert set(layout.keys()) == set(range(n_total)) + coords = list(layout.values()) + assert len(set(coords)) == len(coords) + for r, c in coords: + assert 0 <= r < grid.n_rows + assert 0 <= c < 2 * d - 1 + + +def test_circuit_physical_layout_flip_rows_is_reflection(): + grid = ColorCodeGeometry(5) + base = grid.get_circuit_physical_layout() + flipped = grid.get_circuit_physical_layout(flip_rows=True) + H = grid.n_rows + for q, (r, c) in base.items(): + assert flipped[q] == (H - 1 - r, c) + + +def test_circuit_physical_layout_rejects_bad_id_order(): + grid = ColorCodeGeometry(3) + with pytest.raises(ValueError, match="id_order"): + grid.get_circuit_physical_layout(id_order="bogus") + + +@pytest.mark.parametrize("d", [3, 5]) +def test_superdense_plaquette_labels(d): + grid = ColorCodeGeometry(d) + for i, plaq in enumerate(grid.plaquettes): + labels = grid.superdense_plaquette(i) + assert labels['a1'] == plaq['x_ancilla'] + assert labels['a2'] == plaq['z_ancilla'] + if plaq['weight'] == 6: + qs = [labels[f'q{k}'] for k in range(1, 7)] + assert sorted(qs) == sorted(plaq['data_qubits']) + else: # weight 4: q3/q4 are the unused w6 labels + assert labels['q3'] == -1 + assert labels['q4'] == -1 + qs = [labels['q1'], labels['q2'], labels['q5'], labels['q6']] + assert sorted(qs) == sorted(plaq['data_qubits']) + + +def test_superdense_plaquette_bad_index(): + grid = ColorCodeGeometry(3) + with pytest.raises(IndexError): + grid.superdense_plaquette(-1) + with pytest.raises(IndexError): + grid.superdense_plaquette(grid.num_plaquettes) + + +def test_print_structure_smoke(capsys): + ColorCodeGeometry(3).print_structure() + out = capsys.readouterr().out + assert "Triangular Color Code - Distance 3" in out + assert "Plaquettes (sorted by grid position" in out + + +# --------------------------------------------------------------------------- +# Pauli-word builders (plugin glue) +# --------------------------------------------------------------------------- +from cudaq_qec.plugins.codes.color_code import (_logical_pauli_words, + _plaquette_pauli_words) + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_plaquette_pauli_words(d): + grid = ColorCodeGeometry(d) + x_words, z_words = _plaquette_pauli_words(grid) + assert len(x_words) == len(z_words) == grid.num_plaquettes + for x_word, z_word, plaq in zip(x_words, z_words, grid.plaquettes): + assert len(x_word) == len(z_word) == grid.num_data + support = set(plaq['data_qubits']) + assert {i for i, ch in enumerate(x_word) if ch == 'X'} == support + assert set(x_word) <= {'I', 'X'} + assert {i for i, ch in enumerate(z_word) if ch == 'Z'} == support + assert set(z_word) <= {'I', 'Z'} + + +def test_plaquette_pauli_words_d3_explicit(): + # d=3 plaquettes in grid-sorted order: green [0,1,2,3] (maps to D0), + # red [1,3,5,6] (maps to D1), blue [2,3,4,5] (maps to D3). + grid = ColorCodeGeometry(3) + x_words, z_words = _plaquette_pauli_words(grid) + assert z_words == ["ZZZZIII", "IZIZIZZ", "IIZZZZI"] + assert x_words == ["XXXXIII", "IXIXIXX", "IIXXXXI"] + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_logical_pauli_words(d): + grid = ColorCodeGeometry(d) + x_word, z_word = _logical_pauli_words(grid) + support = set(grid.logical_qubits) + assert {i for i, ch in enumerate(x_word) if ch == 'X'} == support + assert {i for i, ch in enumerate(z_word) if ch == 'Z'} == support + assert len(x_word) == len(z_word) == grid.num_data + + +def test_logical_pauli_words_d3_explicit(): + # d=3 bottom edge is qubits 4,5,6 — same as the Steane-style tail. + grid = ColorCodeGeometry(3) + assert _logical_pauli_words(grid) == ("IIIIXXX", "IIIIZZZ") + + +# --------------------------------------------------------------------------- +# Plugin registration and framework interface +# --------------------------------------------------------------------------- + + +def test_color_code_registered(): + assert 'color_code' in qec.get_available_codes() + + +def test_get_code_requires_distance(): + with pytest.raises(RuntimeError, match="distance"): + qec.get_code('color_code') + + +def test_get_code_rejects_even_distance(): + with pytest.raises((ValueError, RuntimeError), match="odd"): + qec.get_code('color_code', distance=4) + + +@pytest.mark.parametrize("d", [3, 5]) +def test_plugin_interface(d): + code = qec.get_code('color_code', distance=d) + assert isinstance(code, qec.Code) + n = (3 * d * d + 1) // 4 + P = (3 * (d * d - 1)) // 8 + assert code.get_num_data_qubits() == n + assert code.get_num_ancilla_x_qubits() == P + assert code.get_num_ancilla_z_qubits() == P + assert code.get_num_ancilla_qubits() == 2 * P + assert code.get_num_x_stabilizers() == P + assert code.get_num_z_stabilizers() == P + + +@pytest.mark.parametrize("d", [3, 5]) +def test_plugin_parity_matrices(d): + code = qec.get_code('color_code', distance=d) + n = (3 * d * d + 1) // 4 + P = (3 * (d * d - 1)) // 8 + parity = code.get_parity() + assert parity.shape == (2 * P, 2 * n) + parity_x = code.get_parity_x() + parity_z = code.get_parity_z() + assert parity_x.shape == (P, n) + assert parity_z.shape == (P, n) + # Self-dual: X and Z parity blocks contain the same rows (possibly in a + # different canonical sort order). + x_rows = {tuple(r) for r in parity_x} + z_rows = {tuple(r) for r in parity_z} + assert x_rows == z_rows + # Rows are exactly the plaquette supports. + grid = ColorCodeGeometry(d) + expected = {tuple(r) for r in support_matrix(grid)} + assert x_rows == expected + + +@pytest.mark.parametrize("d", [3, 5]) +def test_plugin_observables(d): + code = qec.get_code('color_code', distance=d) + n = (3 * d * d + 1) // 4 + grid = ColorCodeGeometry(d) + Lz = code.get_observables_z() + Lx = code.get_observables_x() + assert Lz.shape == (1, n) + assert Lx.shape == (1, n) + assert set(np.flatnonzero(Lz[0])) == set(grid.logical_qubits) + assert set(np.flatnonzero(Lx[0])) == set(grid.logical_qubits) + + +def test_plugin_stabilizers_list(): + code = qec.get_code('color_code', distance=3) + stabs = code.get_stabilizers() + words = {s.get_pauli_word() for s in stabs} + assert words == { + "ZZZZIII", + "IZIZIZZ", + "IIZZZZI", + "XXXXIII", + "IXIXIXX", + "IIXXXXI", + } + + +# --------------------------------------------------------------------------- +# Superdense memory circuit +# --------------------------------------------------------------------------- + + +def _compass_z_side(grid, p_idx): + # Independent oracle for the Z-ancilla coupling set, from the superdense + # compass labels: bulk -> {q4,q5,q6}; boundary green -> {q1,q2,q6}; + # boundary red -> {q5}; boundary blue -> {q5,q6}. + labels = grid.superdense_plaquette(p_idx) + plaq = grid.plaquettes[p_idx] + if plaq['weight'] == 6: + keys = ['q4', 'q5', 'q6'] + elif plaq['color'] == 'green': + keys = ['q1', 'q2', 'q6'] + elif plaq['color'] == 'red': + keys = ['q5'] + else: + keys = ['q5', 'q6'] + return sorted(labels[k] for k in keys) + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_schedule_shape_and_disjointness(d): + grid = ColorCodeGeometry(d) + N, P = grid.num_data, grid.num_plaquettes + layers = superdense_cnot_layers(grid) + assert len(layers) == 8 + # Layers 1 and 8: pure X-ancilla -> Z-ancilla of the same plaquette. + for li in (0, 7): + assert sorted(layers[li]) == [(N + i, N + P + i) for i in range(P)] + # Every layer's endpoints are disjoint (parallel-executable). + for layer in layers: + seen = [q for e in layer for q in e] + assert len(seen) == len(set(seen)) + # Layers 2-4: data is control; layers 5-7: data is target. + for li in (1, 2, 3): + assert all(c < N and t >= N for c, t in layers[li]) + for li in (4, 5, 6): + assert all(c >= N and t < N for c, t in layers[li]) + # Mirror property: layers 5-7 contain exactly the reversed edges of 2-4. + fwd = {frozenset(e) for li in (1, 2, 3) for e in layers[li]} + bwd = {frozenset(e) for li in (4, 5, 6) for e in layers[li]} + assert fwd == bwd + # Every data-ancilla edge stays inside its plaquette's support. + for li in (1, 2, 3, 4, 5, 6): + for c, t in layers[li]: + dq, anc = (c, t) if c < N else (t, c) + p_idx = (anc - N) % P + assert dq in grid.plaquettes[p_idx]['data_qubits'] + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_z_side_data_matches_compass_rule(d): + grid = ColorCodeGeometry(d) + zs = z_side_data(grid) + assert len(zs) == grid.num_plaquettes + for p_idx in range(grid.num_plaquettes): + assert zs[p_idx] == _compass_z_side(grid, p_idx) + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_every_plaquette_qubit_coupled_exactly_once_per_side(d): + # Each data qubit of a plaquette couples to exactly one of the pair + # (a1 or a2), once on the forward side and once on the mirror side. + grid = ColorCodeGeometry(d) + N, P = grid.num_data, grid.num_plaquettes + layers = superdense_cnot_layers(grid) + for p_idx, plaq in enumerate(grid.plaquettes): + anc_pair = {N + p_idx, N + P + p_idx} + fwd = [e for li in (1, 2, 3) for e in layers[li] if (e[1] in anc_pair)] + touched = sorted(e[0] for e in fwd) + assert touched == sorted(plaq['data_qubits']) + + +# Ground truth: detector sets of the reference superdense construction after +# stim's with_inlined_feedback(), d=3, 3 rounds. +EXPECTED_D3_R3_Z = { + "detectors": [((0.0, 1.0, 0.0, 4.0), [0]), ((1.0, 1.0, 0.0, 3.0), [1]), + ((2.0, 1.0, 0.0, 5.0), [2]), ((0.0, 1.0, 0.0, 1.0), [3, 9]), + ((1.0, 1.0, 0.0, 0.0), [4, 10]), + ((2.0, 1.0, 0.0, 2.0), [5, 11]), + ((0.0, 1.0, 0.0, 4.0), [2, 6]), ((1.0, 1.0, 0.0, 3.0), [7]), + ((2.0, 1.0, 0.0, 5.0), [0, 2, 8]), + ((0.0, 1.0, 0.0, 1.0), [9, 15]), + ((1.0, 1.0, 0.0, 0.0), [10, 16]), + ((2.0, 1.0, 0.0, 2.0), [11, 17]), + ((0.0, 1.0, 0.0, 4.0), [8, 12]), ((1.0, 1.0, 0.0, 3.0), [13]), + ((2.0, 1.0, 0.0, 5.0), [6, 8, 14]), + ((0.0, 1.0, 1.0, 4.0), [14, 18, 19, 20, 21]), + ((1.0, 1.0, 1.0, 3.0), [19, 21, 23, 24]), + ((2.0, 1.0, 1.0, 5.0), [12, 14, 20, 21, 22, 23])], + "observable": [1, 2, 7, 8, 13, 14, 22, 23, 24], +} + +EXPECTED_D3_R3_X = { + "detectors": [((0.0, 1.0, 0.0, 1.0), [3]), ((1.0, 1.0, 0.0, 0.0), [4]), + ((2.0, 1.0, 0.0, 2.0), [5]), ((0.0, 1.0, 0.0, 1.0), [3, 9]), + ((1.0, 1.0, 0.0, 0.0), [4, 10]), + ((2.0, 1.0, 0.0, 2.0), [5, 11]), + ((0.0, 1.0, 0.0, 4.0), [2, 6]), ((1.0, 1.0, 0.0, 3.0), [7]), + ((2.0, 1.0, 0.0, 5.0), [0, 2, 8]), + ((0.0, 1.0, 0.0, 1.0), [9, 15]), + ((1.0, 1.0, 0.0, 0.0), [10, 16]), + ((2.0, 1.0, 0.0, 2.0), [11, 17]), + ((0.0, 1.0, 0.0, 4.0), [8, 12]), ((1.0, 1.0, 0.0, 3.0), [13]), + ((2.0, 1.0, 0.0, 5.0), [6, 8, 14]), + ((0.0, 1.0, 1.0, 1.0), [15, 18, 19, 20, 21]), + ((1.0, 1.0, 1.0, 0.0), [16, 19, 21, 23, 24]), + ((2.0, 1.0, 1.0, 2.0), [17, 20, 21, 22, 23])], + "observable": [18, 19, 20, 21, 22, 23, 24], +} + + +@pytest.mark.parametrize("basis,expected", [("Z", EXPECTED_D3_R3_Z), + ("X", EXPECTED_D3_R3_X)]) +def test_plan_matches_reference_d3_r3(basis, expected): + plan = SuperdensePlan(3, 3, basis) + got = [(tuple(c), sorted(s)) + for c, s in zip(plan.detector_coords, plan.detectors)] + assert got == expected["detectors"] + assert sorted(plan.observable) == expected["observable"] + + +@pytest.mark.parametrize("d,rounds,basis", + [(3, 3, "Z"), (3, 4, "X"), (5, 3, "Z"), (5, 4, "X"), + (7, 5, "Z"), (7, 5, "X")]) +def test_plan_structure(d, rounds, basis): + plan = SuperdensePlan(d, rounds, basis) + P = plan.grid.num_plaquettes + N = plan.grid.num_data + assert len(plan.detectors) == 2 * P * rounds + assert len(plan.detector_coords) == len(plan.detectors) + assert plan.num_records == 2 * P * rounds + N + for s in plan.detectors: + assert all(0 <= i < plan.num_records for i in s) + # Round-0 detectors are single-record, memory basis. + for p in range(P): + (rec,) = plan.detectors[p] + assert rec == (p if basis == "Z" else P + p) + + +def test_detector_bits_xor(): + plan = SuperdensePlan(3, 3, "Z") + m = np.zeros((2, plan.num_records), dtype=np.uint8) + # Flip exactly ONE record of detector 5 in shot 1: precisely the + # detectors containing that record must fire. + rec = sorted(plan.detectors[5])[0] + m[1, rec] = 1 + bits = plan.detector_bits(m) + assert bits.shape == (2, len(plan.detectors)) + assert not bits[0].any() + expected = {j for j, s in enumerate(plan.detectors) if rec in s} + assert set(np.flatnonzero(bits[1]).tolist()) == expected + assert 5 in expected + + +@pytest.mark.parametrize("d,rounds,basis", [(3, 3, "Z"), (3, 3, "X"), + (5, 3, "Z"), (5, 3, "X")]) +def test_dem_construction_succeeds(d, rounds, basis): + # stim validates every declared detector is deterministic; passing this + # call at all is the determinism proof for the inlined parities. + dem = superdense_dem(d, rounds, basis, p_cx=0.01) + plan = SuperdensePlan(d, rounds, basis) + assert dem.num_detectors() == len(plan.detectors) + assert dem.num_observables() == 1 + assert dem.num_error_mechanisms() > 0 + assert dem.detector_error_matrix.shape[0] == len(plan.detectors) + + +@pytest.mark.parametrize("basis,expected", [("Z", 0), ("X", 0)]) +def test_noiseless_sampling_deterministic(basis, expected): + syndromes, data, logical = superdense_sample(3, + 3, + basis, + p_cx=0.0, + shots=50) + assert syndromes.shape == (50, 18) + assert data.shape == (50, 7) + assert not syndromes.any() + assert np.all(logical == expected) + + +def test_noisy_sampling_fires_detectors(): + syndromes, _, _ = superdense_sample(3, 4, "Z", p_cx=0.05, shots=200) + assert syndromes.any() + # No detector column should fire in (nearly) all shots — that would + # indicate a broken parity rather than noise. + assert syndromes.mean(axis=0).max() < 0.75 + + +def test_decoding_reduces_logical_errors(): + cudaq.set_random_seed(13) + d, rounds, p = 3, 4, 0.01 + dem = superdense_dem(d, rounds, "Z", p_cx=p) + syndromes, _, logical = superdense_sample(d, + rounds, + "Z", + p_cx=p, + shots=1000) + decoder = qec.get_decoder('single_error_lut', dem.detector_error_matrix) + dr = decoder.decode_batch(syndromes) + err = np.asarray(dr.result, dtype=np.uint8) + pred = ((dem.observables_flips_matrix @ err.T) % 2).flatten() + n_without = int(logical.sum()) + n_with = int((pred ^ logical).sum()) + print(f"logical errors without decoding: {n_without}, with: {n_with}") + assert n_with < n_without + + +_DATA_DIR = os.path.join(os.path.dirname(__file__), "data") + + +def _dem_signature(dem_text, stim_mod): + # Canonical multiset {(detectors, observables) -> merged probability}. + def merge(p, q): + return p + q - 2.0 * p * q + + sig = {} + for inst in stim_mod.DetectorErrorModel(dem_text).flattened(): + if inst.type != "error": + continue + prob = inst.args_copy()[0] + dets, obss = [], [] + for t in inst.targets_copy(): + if t.is_relative_detector_id(): + dets.append(t.val) + elif t.is_logical_observable_id(): + obss.append(t.val) + key = (tuple(sorted(dets)), tuple(sorted(obss))) + sig[key] = merge(sig[key], prob) if key in sig else prob + return sig + + +@pytest.mark.parametrize("basis", ["Z", "X"]) +def test_dem_matches_reference_golden(basis): + stim_mod = pytest.importorskip("stim") + with open(os.path.join(_DATA_DIR, + f"superdense_golden_d3_r3_{basis}.dem")) as f: + golden = f.read() + golden = "\n".join(l for l in golden.splitlines() if not l.startswith("#")) + plan = SuperdensePlan(3, 3, basis) + # An (empty) noise model must be passed or in-kernel apply_noise is a + # silent no-op and the DEM comes back with zero error mechanisms. + ours_text = cudaq.dem_from_kernel(superdense_memory, + *_kernel_args(plan, 0.01), + noise_model=cudaq.NoiseModel()) + ref = _dem_signature(golden, stim_mod) + got = _dem_signature(ours_text, stim_mod) + assert set(ref) == set(got), ( + f"error-mechanism signatures differ: ref-only " + f"{sorted(set(ref) - set(got))[:5]}, ours-only " + f"{sorted(set(got) - set(ref))[:5]}") + for k in ref: + assert np.isclose(ref[k], got[k], atol=1e-6, rtol=1e-4), ( + f"probability mismatch at {k}: ref={ref[k]}, ours={got[k]}") + + +if __name__ == "__main__": + pytest.main() From 30fc4c7d73e8f5a9c48fff856b8fe1b9d9f1a6ac Mon Sep 17 00:00:00 2001 From: kvmto Date: Wed, 8 Jul 2026 16:53:04 +0200 Subject: [PATCH 6/8] improved testing Signed-off-by: kvmto --- .../tests/data/superdense_golden_d3_r3_X.dem | 334 ------------------ .../tests/data/superdense_golden_d3_r3_Z.dem | 303 ---------------- libs/qec/python/tests/test_color_code.py | 63 +++- 3 files changed, 58 insertions(+), 642 deletions(-) delete mode 100644 libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem delete mode 100644 libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem diff --git a/libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem b/libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem deleted file mode 100644 index 1cf14cf76..000000000 --- a/libs/qec/python/tests/data/superdense_golden_d3_r3_X.dem +++ /dev/null @@ -1,334 +0,0 @@ -# Reference superdense color-code DEM, d=3, 3 rounds, DEPOLARIZE2(0.01) per CX, perfect final round. -error(0.001338700097173320998) D0 D1 D2 D6 D7 D8 L0 -error(0.0006697986788568588423) D0 D1 D2 D6 D7 L0 -error(0.0006697986788568588423) D0 D1 D2 D6 L0 -error(0.001338700097173320998) D0 D1 D2 D7 D8 L0 -error(0.0006697986788568588423) D0 D1 D2 D7 L0 -error(0.002673815958446297981) D0 D1 D2 D8 L0 -error(0.003340032800510209492) D0 D1 D2 L0 -error(0.002006705456917235505) D0 D1 D4 -error(0.002006705456917235505) D0 D1 D4 D7 -error(0.0006697986788568588423) D0 D1 D4 D7 D8 -error(0.0006697986788568588423) D0 D1 D4 D8 -error(0.001338700097173320998) D0 D1 D5 D6 D7 D8 L0 -error(0.0006697986788568588423) D0 D1 D5 D6 D7 L0 -error(0.0006697986788568588423) D0 D1 D5 D6 L0 -error(0.0006697986788568588423) D0 D1 D5 D7 D8 L0 -error(0.0006697986788568588423) D0 D1 D5 D8 L0 -error(0.001338700097173320998) D0 D1 D5 L0 -error(0.001338700097173320998) D0 D1 D6 D7 L0 -error(0.001338700097173320998) D0 D1 D6 L0 -error(0.002673815958446297981) D0 D1 D7 L0 -error(0.002673815958446297981) D0 D1 L0 -error(0.002006705456917235505) D0 D2 D3 -error(0.002006705456917235505) D0 D2 D3 D6 -error(0.0006697986788568588423) D0 D2 D3 D6 D7 -error(0.0006697986788568588423) D0 D2 D3 D7 -error(0.005333333333333313206) D0 D2 D5 -error(0.005333333333333313206) D0 D2 D5 D8 -error(0.001338700097173320998) D0 D2 D6 D8 L0 -error(0.001338700097173320998) D0 D2 D6 L0 -error(0.002673815958446297981) D0 D2 D8 L0 -error(0.002673815958446297981) D0 D2 L0 -error(0.007978628588222850399) D0 D3 -error(0.003340032800510209492) D0 D3 D6 -error(0.002006705456917235505) D0 D3 D6 D7 -error(0.001338700097173320998) D0 D3 D6 D7 D8 -error(0.001338700097173320998) D0 D3 D6 D8 -error(0.0006697986788568588423) D0 D3 D7 D8 -error(0.004669790293214320931) D0 D3 D8 -error(0.001338700097173320998) D0 D4 D5 D6 D7 D8 L0 -error(0.0006697986788568588423) D0 D4 D5 D6 D7 L0 -error(0.0006697986788568588423) D0 D4 D5 D6 L0 -error(0.0006697986788568588423) D0 D4 D5 D7 D8 L0 -error(0.0006697986788568588423) D0 D4 D5 D8 L0 -error(0.001338700097173320998) D0 D4 D5 L0 -error(0.002006705456917235505) D0 D4 D6 D7 L0 -error(0.0006697986788568588423) D0 D4 D6 L0 -error(0.0006697986788568588423) D0 D4 D7 L0 -error(0.002006705456917235505) D0 D4 L0 -error(0.001338700097173320998) D0 D5 D6 D8 L0 -error(0.001338700097173320998) D0 D5 D6 L0 -error(0.001338700097173320998) D0 D5 D8 L0 -error(0.001338700097173320998) D0 D5 L0 -error(0.002673815958446297981) D0 D6 L0 -error(0.002673815958446297981) D0 L0 -error(0.0006697986788568588423) D1 D2 D3 D6 D7 D8 L0 -error(0.0006697986788568588423) D1 D2 D3 D6 D7 L0 -error(0.001338700097173320998) D1 D2 D3 D6 L0 -error(0.0006697986788568588423) D1 D2 D3 D7 D8 L0 -error(0.0006697986788568588423) D1 D2 D3 D7 L0 -error(0.001338700097173320998) D1 D2 D3 L0 -error(0.0006697986788568588423) D1 D2 D6 D7 L0 -error(0.0006697986788568588423) D1 D2 D6 D8 L0 -error(0.001338700097173320998) D1 D2 D7 D8 L0 -error(0.0006697986788568588423) D1 D2 D7 L0 -error(0.002006705456917235505) D1 D2 D8 L0 -error(0.002673815958446297981) D1 D2 L0 -error(0.01126536362635755656) D1 D4 -error(0.001338700097173320998) D1 D4 D6 -error(0.0006697986788568588423) D1 D4 D6 D7 -error(0.0006697986788568588423) D1 D4 D6 D7 D8 -error(0.004005357180252827609) D1 D4 D7 -error(0.002673815958446297981) D1 D4 D7 D8 -error(0.0006697986788568588423) D1 D4 D8 -error(0.0006697986788568588423) D1 D5 D6 D7 L0 -error(0.0006697986788568588423) D1 D5 D6 D8 L0 -error(0.002006705456917235505) D1 D5 D7 D8 L0 -error(0.002673815958446297981) D1 D5 D8 L0 -error(0.004669790293214320931) D1 D5 L0 -error(0.002673815958446297981) D1 D7 L0 -error(0.002673815958446297981) D1 L0 -error(0.0006697986788568588423) D2 D3 D6 D8 L0 -error(0.004669790293214320931) D2 D3 D6 L0 -error(0.0006697986788568588423) D2 D3 D8 L0 -error(0.004669790293214320931) D2 D3 L0 -error(0.001338700097173320998) D2 D4 D7 D8 L0 -error(0.001338700097173320998) D2 D4 D7 L0 -error(0.001338700097173320998) D2 D4 D8 L0 -error(0.001338700097173320998) D2 D4 L0 -error(0.007978628588222850399) D2 D5 -error(0.001338700097173320998) D2 D5 D6 -error(0.001338700097173320998) D2 D5 D6 D7 -error(0.0006697986788568588423) D2 D5 D6 D7 D8 -error(0.004669790293214320931) D2 D5 D6 D8 -error(0.0006697986788568588423) D2 D5 D7 D8 -error(0.004669790293214320931) D2 D5 D8 -error(0.0006697986788568588423) D2 D6 D8 L0 -error(0.0006697986788568588423) D2 D6 L0 -error(0.002006705456917235505) D2 D8 L0 -error(0.002006705456917235505) D2 L0 -error(0.001338700097173320998) D3 D4 D5 D6 D7 D8 L0 -error(0.001338700097173320998) D3 D4 D5 D6 D7 D14 L0 -error(0.0006697986788568588423) D3 D4 D5 D6 D7 L0 -error(0.0006697986788568588423) D3 D4 D5 D6 D12 L0 -error(0.001338700097173320998) D3 D4 D5 D6 D13 D14 L0 -error(0.0006697986788568588423) D3 D4 D5 D7 D13 L0 -error(0.0006697986788568588423) D3 D4 D5 D8 D12 D13 L0 -error(0.001338700097173320998) D3 D4 D5 D8 D14 L0 -error(0.0006697986788568588423) D3 D4 D5 D8 L0 -error(0.001338700097173320998) D3 D4 D5 D12 D13 D14 L0 -error(0.003340032800510209492) D3 D4 D5 L0 -error(0.0006697986788568588423) D3 D4 D6 D7 D10 -error(0.0006697986788568588423) D3 D4 D6 D7 D10 D14 -error(0.002006705456917235505) D3 D4 D6 D7 L0 -error(0.0006697986788568588423) D3 D4 D6 D10 D13 -error(0.0006697986788568588423) D3 D4 D6 D10 D13 D14 -error(0.0006697986788568588423) D3 D4 D6 D12 L0 -error(0.001338700097173320998) D3 D4 D6 D13 L0 -error(0.001338700097173320998) D3 D4 D7 D10 D13 -error(0.0006697986788568588423) D3 D4 D7 D11 D12 L0 -error(0.0006697986788568588423) D3 D4 D7 D11 D13 D14 L0 -error(0.0006697986788568588423) D3 D4 D7 D12 L0 -error(0.001338700097173320998) D3 D4 D7 D13 L0 -error(0.0006697986788568588423) D3 D4 D8 D11 D12 D13 L0 -error(0.0006697986788568588423) D3 D4 D8 D11 D14 L0 -error(0.001338700097173320998) D3 D4 D10 -error(0.001338700097173320998) D3 D4 D11 D12 D13 D14 L0 -error(0.001338700097173320998) D3 D4 D11 L0 -error(0.001338700097173320998) D3 D4 D12 D13 L0 -error(0.003340032800510209492) D3 D4 L0 -error(0.0006697986788568588423) D3 D5 D6 D7 D8 D11 -error(0.0006697986788568588423) D3 D5 D6 D7 D11 D14 -error(0.0006697986788568588423) D3 D5 D6 D8 D11 -error(0.001338700097173320998) D3 D5 D6 D8 L0 -error(0.0006697986788568588423) D3 D5 D6 D9 -error(0.001338700097173320998) D3 D5 D6 D9 D12 -error(0.0006697986788568588423) D3 D5 D6 D9 D13 -error(0.0006697986788568588423) D3 D5 D6 D11 D14 -error(0.0006697986788568588423) D3 D5 D6 D12 L0 -error(0.001338700097173320998) D3 D5 D6 D14 L0 -error(0.0006697986788568588423) D3 D5 D6 L0 -error(0.004005357180252827609) D3 D5 D8 D11 D14 -error(0.0006697986788568588423) D3 D5 D8 D12 L0 -error(0.001338700097173320998) D3 D5 D8 D14 L0 -error(0.0006697986788568588423) D3 D5 D8 L0 -error(0.001338700097173320998) D3 D5 D9 -error(0.0006697986788568588423) D3 D5 D9 D12 -error(0.0006697986788568588423) D3 D5 D9 D12 D13 -error(0.004005357180252827609) D3 D5 D11 -error(0.001338700097173320998) D3 D5 D12 D14 L0 -error(0.002673815958446297981) D3 D5 L0 -error(0.001338700097173320998) D3 D6 D9 -error(0.002673815958446297981) D3 D6 D9 D12 -error(0.001338700097173320998) D3 D6 D9 D12 D13 -error(0.0006697986788568588423) D3 D6 D9 D13 D14 -error(0.004669790293214320931) D3 D6 D9 D14 -error(0.0006697986788568588423) D3 D6 D10 D11 D12 D13 L0 -error(0.0006697986788568588423) D3 D6 D10 D11 D14 L0 -error(0.0006697986788568588423) D3 D6 D10 D12 D13 L0 -error(0.0006697986788568588423) D3 D6 D10 L0 -error(0.0006697986788568588423) D3 D6 D11 D12 L0 -error(0.0006697986788568588423) D3 D6 D11 D14 L0 -error(0.001338700097173320998) D3 D6 D12 L0 -error(0.002673815958446297981) D3 D6 L0 -error(0.0006697986788568588423) D3 D7 D10 D11 D12 L0 -error(0.0006697986788568588423) D3 D7 D10 D11 D13 D14 L0 -error(0.0006697986788568588423) D3 D7 D10 D12 L0 -error(0.0006697986788568588423) D3 D7 D10 D13 L0 -error(0.0006697986788568588423) D3 D8 D11 D12 L0 -error(0.0006697986788568588423) D3 D8 D11 D14 L0 -error(0.006657753962803452177) D3 D9 -error(0.0006697986788568588423) D3 D9 D12 -error(0.0006697986788568588423) D3 D9 D12 D13 -error(0.001338700097173320998) D3 D9 D12 D13 D14 -error(0.001338700097173320998) D3 D9 D12 D14 -error(0.001338700097173320998) D3 D10 D11 D12 D13 D14 L0 -error(0.001338700097173320998) D3 D10 D11 L0 -error(0.001338700097173320998) D3 D10 D12 D13 L0 -error(0.001338700097173320998) D3 D10 L0 -error(0.001338700097173320998) D3 D11 D12 D14 L0 -error(0.001338700097173320998) D3 D11 L0 -error(0.001338700097173320998) D3 D12 L0 -error(0.002673815958446297981) D3 L0 -error(0.001338700097173320998) D4 D5 D6 D9 D12 L0 -error(0.0006697986788568588423) D4 D5 D6 D9 D13 D14 L0 -error(0.0006697986788568588423) D4 D5 D6 D9 D13 L0 -error(0.002006705456917235505) D4 D5 D7 D8 L0 -error(0.0006697986788568588423) D4 D5 D7 D13 L0 -error(0.001338700097173320998) D4 D5 D7 D14 L0 -error(0.0006697986788568588423) D4 D5 D8 D12 D13 L0 -error(0.0006697986788568588423) D4 D5 D8 D12 D14 L0 -error(0.0006697986788568588423) D4 D5 D8 D14 L0 -error(0.0006697986788568588423) D4 D5 D9 D12 D13 D14 L0 -error(0.0006697986788568588423) D4 D5 D9 D12 D13 L0 -error(0.001338700097173320998) D4 D5 D9 L0 -error(0.001338700097173320998) D4 D5 D13 D14 L0 -error(0.003340032800510209492) D4 D5 L0 -error(0.0006697986788568588423) D4 D6 D7 D8 D11 L0 -error(0.0006697986788568588423) D4 D6 D7 D11 D14 L0 -error(0.0006697986788568588423) D4 D7 D8 D11 L0 -error(0.004669790293214320931) D4 D7 D10 -error(0.001338700097173320998) D4 D7 D10 D12 -error(0.002673815958446297981) D4 D7 D10 D13 -error(0.001338700097173320998) D4 D7 D10 D13 D14 -error(0.0006697986788568588423) D4 D7 D10 D14 -error(0.0006697986788568588423) D4 D7 D11 D13 D14 L0 -error(0.0006697986788568588423) D4 D7 D11 D14 L0 -error(0.0006697986788568588423) D4 D7 D11 L0 -error(0.001338700097173320998) D4 D7 D13 L0 -error(0.007978628588222850399) D4 D7 L0 -error(0.0006697986788568588423) D4 D8 D11 D12 D13 L0 -error(0.0006697986788568588423) D4 D8 D11 D12 D14 L0 -error(0.001338700097173320998) D4 D8 D11 D14 L0 -error(0.006657753962803452177) D4 D10 -error(0.0006697986788568588423) D4 D10 D12 D13 -error(0.0006697986788568588423) D4 D10 D12 D13 D14 -error(0.001338700097173320998) D4 D10 D13 -error(0.001338700097173320998) D4 D10 D13 D14 -error(0.001338700097173320998) D4 D11 D13 D14 L0 -error(0.002673815958446297981) D4 D11 L0 -error(0.001338700097173320998) D4 D13 L0 -error(0.007978628588222850399) D4 L0 -error(0.0006697986788568588423) D5 D6 D7 D10 D14 L0 -error(0.0006697986788568588423) D5 D6 D8 L0 -error(0.004005357180252827609) D5 D6 D9 D12 L0 -error(0.0006697986788568588423) D5 D6 D9 D14 L0 -error(0.0006697986788568588423) D5 D6 D9 L0 -error(0.0006697986788568588423) D5 D6 D10 D13 D14 L0 -error(0.0006697986788568588423) D5 D6 L0 -error(0.0006697986788568588423) D5 D7 D8 D11 -error(0.001338700097173320998) D5 D7 D10 D13 L0 -error(0.0006697986788568588423) D5 D7 D10 D14 L0 -error(0.0006697986788568588423) D5 D7 D11 D14 -error(0.0006697986788568588423) D5 D8 D11 -error(0.001338700097173320998) D5 D8 D11 D12 -error(0.001338700097173320998) D5 D8 D11 D12 D13 -error(0.004005357180252827609) D5 D8 D11 D12 D14 -error(0.002673815958446297981) D5 D8 D11 D14 -error(0.0006697986788568588423) D5 D8 D12 D14 L0 -error(0.0006697986788568588423) D5 D8 D12 L0 -error(0.0006697986788568588423) D5 D8 D14 L0 -error(0.004005357180252827609) D5 D8 L0 -error(0.0006697986788568588423) D5 D9 D12 D14 L0 -error(0.0006697986788568588423) D5 D9 D12 L0 -error(0.004005357180252827609) D5 D9 L0 -error(0.0006697986788568588423) D5 D10 D13 D14 L0 -error(0.001338700097173320998) D5 D10 L0 -error(0.006657753962803452177) D5 D11 -error(0.0006697986788568588423) D5 D11 D12 D13 D14 -error(0.0006697986788568588423) D5 D11 D12 D14 -error(0.0006697986788568588423) D5 D11 D13 D14 -error(0.001338700097173320998) D5 D11 D14 -error(0.001338700097173320998) D5 D14 L0 -error(0.004669790293214320931) D5 L0 -error(0.01257390183676828158) D6 -error(0.005333333333333313206) D6 D7 -error(0.003340032800510209492) D6 D7 D8 -error(0.0006697986788568588423) D6 D7 D10 L0 -error(0.001338700097173320998) D6 D7 D14 -error(0.006657753962803452177) D6 D8 -error(0.0006697986788568588423) D6 D8 D11 L0 -error(0.0006697986788568588423) D6 D9 D10 D11 D12 D13 L0 -error(0.0006697986788568588423) D6 D9 D10 D11 D14 L0 -error(0.0006697986788568588423) D6 D9 D10 D12 D13 L0 -error(0.0006697986788568588423) D6 D9 D10 L0 -error(0.0006697986788568588423) D6 D9 D11 D12 L0 -error(0.0006697986788568588423) D6 D9 D11 D14 L0 -error(0.0006697986788568588423) D6 D9 D12 L0 -error(0.0006697986788568588423) D6 D9 L0 -error(0.0006697986788568588423) D6 D10 D13 L0 -error(0.0006697986788568588423) D6 D11 D14 L0 -error(0.006657753962803452177) D6 D12 -error(0.001338700097173320998) D6 D12 D13 -error(0.001338700097173320998) D6 D13 -error(0.001338700097173320998) D6 D13 D14 -error(0.005333333333333313206) D6 D14 -error(0.01387893656672014447) D7 -error(0.005333333333333313206) D7 D8 -error(0.0006697986788568588423) D7 D10 D11 D13 D14 L0 -error(0.0006697986788568588423) D7 D10 D11 L0 -error(0.004669790293214320931) D7 D10 D13 L0 -error(0.001338700097173320998) D7 D10 L0 -error(0.001338700097173320998) D7 D12 -error(0.006657753962803452177) D7 D13 -error(0.001338700097173320998) D7 D13 D14 -error(0.001338700097173320998) D7 D14 -error(0.01647853308100971984) D8 -error(0.0006697986788568588423) D8 D11 D12 D14 L0 -error(0.0006697986788568588423) D8 D11 D12 L0 -error(0.001338700097173320998) D8 D11 D14 L0 -error(0.0006697986788568588423) D8 D11 L0 -error(0.001338700097173320998) D8 D12 -error(0.001338700097173320998) D8 D12 D13 -error(0.004005357180252827609) D8 D12 D14 -error(0.006657753962803452177) D8 D14 -error(0.0006697986788568588423) D9 D10 D11 D12 D13 D14 L0 -error(0.0006697986788568588423) D9 D10 D11 L0 -error(0.0006697986788568588423) D9 D10 D12 D13 L0 -error(0.0006697986788568588423) D9 D10 L0 -error(0.0006697986788568588423) D9 D11 D12 D14 L0 -error(0.0006697986788568588423) D9 D11 L0 -error(0.0006697986788568588423) D9 D12 L0 -error(0.0006697986788568588423) D9 L0 -error(0.0006697986788568588423) D10 D11 D13 D14 L0 -error(0.0006697986788568588423) D10 D11 L0 -error(0.001338700097173320998) D10 D13 L0 -error(0.004669790293214320931) D10 L0 -error(0.001338700097173320998) D11 D14 L0 -error(0.002006705456917235505) D11 L0 -error(0.001338700097173320998) D12 -error(0.002006705456917235505) D12 D13 -error(0.002673815958446297981) D12 D13 D14 -error(0.002006705456917235505) D12 D14 -error(0.001338700097173320998) D13 -error(0.002006705456917235505) D13 D14 -error(0.001338700097173320998) D14 -detector(0, 1, 0, 1) D0 -detector(1, 1, 0, 0) D1 -detector(2, 1, 0, 2) D2 -detector(0, 1, 0, 1) D3 -detector(1, 1, 0, 0) D4 -detector(2, 1, 0, 2) D5 -detector(0, 1, 0, 4) D6 -detector(1, 1, 0, 3) D7 -detector(2, 1, 0, 5) D8 -detector(0, 1, 0, 1) D9 -detector(1, 1, 0, 0) D10 -detector(2, 1, 0, 2) D11 -detector(0, 1, 0, 4) D12 -detector(1, 1, 0, 3) D13 -detector(2, 1, 0, 5) D14 -detector(0, 1, 1, 1) D15 -detector(1, 1, 1, 0) D16 -detector(2, 1, 1, 2) D17 diff --git a/libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem b/libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem deleted file mode 100644 index e6928b85e..000000000 --- a/libs/qec/python/tests/data/superdense_golden_d3_r3_Z.dem +++ /dev/null @@ -1,303 +0,0 @@ -# Reference superdense color-code DEM, d=3, 3 rounds, DEPOLARIZE2(0.01) per CX, perfect final round. -error(0.003340032800510209492) D0 -error(0.001338700097173320998) D0 D1 -error(0.001338700097173320998) D0 D1 D2 -error(0.001338700097173320998) D0 D1 D2 D5 -error(0.001338700097173320998) D0 D1 D4 -error(0.001338700097173320998) D0 D1 D4 D8 -error(0.001338700097173320998) D0 D1 D5 D8 -error(0.002673815958446297981) D0 D1 D8 -error(0.001338700097173320998) D0 D2 -error(0.001338700097173320998) D0 D2 D5 -error(0.003340032800510209492) D0 D3 -error(0.0006697986788568588423) D0 D3 D4 -error(0.0006697986788568588423) D0 D3 D4 D5 D6 D7 -error(0.0006697986788568588423) D0 D3 D4 D5 D8 -error(0.0006697986788568588423) D0 D3 D4 D6 D7 -error(0.0006697986788568588423) D0 D3 D5 D6 -error(0.0006697986788568588423) D0 D3 D5 D8 -error(0.009953312530086681764) D0 D3 D6 -error(0.001338700097173320998) D0 D3 D6 D7 -error(0.001338700097173320998) D0 D3 D7 -error(0.001338700097173320998) D0 D3 D7 D8 -error(0.005333333333333313206) D0 D3 D8 -error(0.0006697986788568588423) D0 D4 -error(0.0006697986788568588423) D0 D4 D5 D6 D7 -error(0.0006697986788568588423) D0 D4 D5 D8 -error(0.0006697986788568588423) D0 D4 D6 D7 -error(0.001338700097173320998) D0 D4 D7 -error(0.001338700097173320998) D0 D4 D7 D8 -error(0.0006697986788568588423) D0 D5 D6 -error(0.002006705456917235505) D0 D5 D8 -error(0.009953312530086681764) D0 D6 -error(0.001338700097173320998) D0 D6 D7 -error(0.002673815958446297981) D0 D7 -error(0.002673815958446297981) D0 D7 D8 -error(0.006657753962803452177) D0 D8 -error(0.001338700097173320998) D1 D2 D5 L0 -error(0.001338700097173320998) D1 D2 L0 -error(0.0006697986788568588423) D1 D4 D5 D6 -error(0.001338700097173320998) D1 D4 D5 D7 D8 -error(0.0006697986788568588423) D1 D4 D5 L0 -error(0.002006705456917235505) D1 D4 D6 -error(0.01060977777777773884) D1 D4 D7 -error(0.001338700097173320998) D1 D4 D7 D8 -error(0.001338700097173320998) D1 D4 D8 L0 -error(0.005995987492949031786) D1 D4 L0 -error(0.0006697986788568588423) D1 D5 D6 -error(0.001338700097173320998) D1 D5 D7 D8 -error(0.001338700097173320998) D1 D5 D8 L0 -error(0.0006697986788568588423) D1 D5 L0 -error(0.002006705456917235505) D1 D6 -error(0.01060977777777773884) D1 D7 -error(0.001338700097173320998) D1 D7 D8 -error(0.002673815958446297981) D1 D8 L0 -error(0.005995987492949031786) D1 L0 -error(0.002673815958446297981) D2 D5 D6 -error(0.002673815958446297981) D2 D5 D6 D7 -error(0.005333333333333313206) D2 D5 D6 D8 L0 -error(0.01060977777777773884) D2 D5 D8 -error(0.001338700097173320998) D2 D5 L0 -error(0.002673815958446297981) D2 D6 -error(0.002673815958446297981) D2 D6 D7 -error(0.005333333333333313206) D2 D6 D8 L0 -error(0.01060977777777773884) D2 D8 -error(0.001338700097173320998) D2 L0 -error(0.01518047719643240284) D3 -error(0.002673815958446297981) D3 D4 -error(0.003340032800510209492) D3 D4 D5 -error(0.001338700097173320998) D3 D4 D5 D6 D7 D8 -error(0.001338700097173320998) D3 D4 D5 D6 D7 D14 -error(0.0006697986788568588423) D3 D4 D5 D6 D12 -error(0.001338700097173320998) D3 D4 D5 D6 D13 D14 -error(0.0006697986788568588423) D3 D4 D5 D7 D13 -error(0.0006697986788568588423) D3 D4 D5 D8 D12 D13 -error(0.001338700097173320998) D3 D4 D5 D8 D14 -error(0.001338700097173320998) D3 D4 D5 D12 D13 D14 -error(0.001338700097173320998) D3 D4 D6 D7 -error(0.0006697986788568588423) D3 D4 D6 D7 D10 -error(0.0006697986788568588423) D3 D4 D6 D7 D10 D14 -error(0.0006697986788568588423) D3 D4 D6 D10 D13 -error(0.0006697986788568588423) D3 D4 D6 D10 D13 D14 -error(0.0006697986788568588423) D3 D4 D6 D12 -error(0.001338700097173320998) D3 D4 D6 D13 -error(0.001338700097173320998) D3 D4 D7 D10 D13 -error(0.0006697986788568588423) D3 D4 D7 D11 D12 -error(0.0006697986788568588423) D3 D4 D7 D11 D13 D14 -error(0.0006697986788568588423) D3 D4 D7 D12 -error(0.001338700097173320998) D3 D4 D7 D13 -error(0.0006697986788568588423) D3 D4 D8 D11 D12 D13 -error(0.0006697986788568588423) D3 D4 D8 D11 D14 -error(0.001338700097173320998) D3 D4 D10 -error(0.001338700097173320998) D3 D4 D11 -error(0.001338700097173320998) D3 D4 D11 D12 D13 D14 -error(0.001338700097173320998) D3 D4 D12 D13 -error(0.002673815958446297981) D3 D5 -error(0.0006697986788568588423) D3 D5 D6 D7 D8 D11 -error(0.0006697986788568588423) D3 D5 D6 D7 D11 D14 -error(0.001338700097173320998) D3 D5 D6 D8 -error(0.0006697986788568588423) D3 D5 D6 D8 D11 -error(0.0006697986788568588423) D3 D5 D6 D9 -error(0.001338700097173320998) D3 D5 D6 D9 D12 -error(0.0006697986788568588423) D3 D5 D6 D9 D13 -error(0.0006697986788568588423) D3 D5 D6 D11 D14 -error(0.0006697986788568588423) D3 D5 D6 D12 -error(0.001338700097173320998) D3 D5 D6 D14 -error(0.004005357180252827609) D3 D5 D8 D11 D14 -error(0.0006697986788568588423) D3 D5 D8 D12 -error(0.001338700097173320998) D3 D5 D8 D14 -error(0.001338700097173320998) D3 D5 D9 -error(0.0006697986788568588423) D3 D5 D9 D12 -error(0.0006697986788568588423) D3 D5 D9 D12 D13 -error(0.004005357180252827609) D3 D5 D11 -error(0.001338700097173320998) D3 D5 D12 D14 -error(0.004005357180252827609) D3 D6 -error(0.002006705456917235505) D3 D6 D7 -error(0.002006705456917235505) D3 D6 D7 D8 -error(0.002006705456917235505) D3 D6 D8 -error(0.001338700097173320998) D3 D6 D9 -error(0.002673815958446297981) D3 D6 D9 D12 -error(0.001338700097173320998) D3 D6 D9 D12 D13 -error(0.0006697986788568588423) D3 D6 D9 D13 D14 -error(0.004669790293214320931) D3 D6 D9 D14 -error(0.0006697986788568588423) D3 D6 D10 -error(0.0006697986788568588423) D3 D6 D10 D11 D12 D13 -error(0.0006697986788568588423) D3 D6 D10 D11 D14 -error(0.0006697986788568588423) D3 D6 D10 D12 D13 -error(0.0006697986788568588423) D3 D6 D11 D12 -error(0.0006697986788568588423) D3 D6 D11 D14 -error(0.001338700097173320998) D3 D6 D12 -error(0.0006697986788568588423) D3 D7 D10 D11 D12 -error(0.0006697986788568588423) D3 D7 D10 D11 D13 D14 -error(0.0006697986788568588423) D3 D7 D10 D12 -error(0.0006697986788568588423) D3 D7 D10 D13 -error(0.0006697986788568588423) D3 D8 D11 D12 -error(0.0006697986788568588423) D3 D8 D11 D14 -error(0.006657753962803452177) D3 D9 -error(0.0006697986788568588423) D3 D9 D12 -error(0.0006697986788568588423) D3 D9 D12 D13 -error(0.001338700097173320998) D3 D9 D12 D13 D14 -error(0.001338700097173320998) D3 D9 D12 D14 -error(0.001338700097173320998) D3 D10 -error(0.001338700097173320998) D3 D10 D11 -error(0.001338700097173320998) D3 D10 D11 D12 D13 D14 -error(0.001338700097173320998) D3 D10 D12 D13 -error(0.001338700097173320998) D3 D11 -error(0.001338700097173320998) D3 D11 D12 D14 -error(0.001338700097173320998) D3 D12 -error(0.01647853308100971984) D4 -error(0.004005357180252827609) D4 D5 -error(0.001338700097173320998) D4 D5 D6 D7 D8 -error(0.001338700097173320998) D4 D5 D6 D9 D12 -error(0.0006697986788568588423) D4 D5 D6 D9 D13 -error(0.0006697986788568588423) D4 D5 D6 D9 D13 D14 -error(0.001338700097173320998) D4 D5 D7 D8 L0 -error(0.0006697986788568588423) D4 D5 D7 D13 -error(0.001338700097173320998) D4 D5 D7 D14 L0 -error(0.0006697986788568588423) D4 D5 D8 D12 D13 -error(0.0006697986788568588423) D4 D5 D8 D12 D14 L0 -error(0.0006697986788568588423) D4 D5 D8 D14 -error(0.001338700097173320998) D4 D5 D9 -error(0.0006697986788568588423) D4 D5 D9 D12 D13 -error(0.0006697986788568588423) D4 D5 D9 D12 D13 D14 -error(0.001338700097173320998) D4 D5 D13 D14 L0 -error(0.002006705456917235505) D4 D6 D7 -error(0.0006697986788568588423) D4 D6 D7 D8 -error(0.0006697986788568588423) D4 D6 D7 D8 D11 -error(0.0006697986788568588423) D4 D6 D7 D11 D14 -error(0.0006697986788568588423) D4 D7 D8 D11 L0 -error(0.002006705456917235505) D4 D7 D8 L0 -error(0.001338700097173320998) D4 D7 D10 D12 -error(0.002673815958446297981) D4 D7 D10 D13 -error(0.001338700097173320998) D4 D7 D10 D13 D14 -error(0.0006697986788568588423) D4 D7 D10 D14 L0 -error(0.004669790293214320931) D4 D7 D10 L0 -error(0.0006697986788568588423) D4 D7 D11 D13 D14 -error(0.0006697986788568588423) D4 D7 D11 D14 L0 -error(0.0006697986788568588423) D4 D7 D11 L0 -error(0.001338700097173320998) D4 D7 D13 -error(0.004005357180252827609) D4 D7 L0 -error(0.0006697986788568588423) D4 D8 D11 D12 D13 -error(0.0006697986788568588423) D4 D8 D11 D12 D14 L0 -error(0.001338700097173320998) D4 D8 D11 D14 -error(0.006657753962803452177) D4 D10 -error(0.0006697986788568588423) D4 D10 D12 D13 -error(0.0006697986788568588423) D4 D10 D12 D13 D14 -error(0.001338700097173320998) D4 D10 D13 D14 L0 -error(0.001338700097173320998) D4 D10 D13 L0 -error(0.002673815958446297981) D4 D11 -error(0.001338700097173320998) D4 D11 D13 D14 L0 -error(0.001338700097173320998) D4 D13 L0 -error(0.01906422791000844316) D5 -error(0.002006705456917235505) D5 D6 D7 D8 -error(0.0006697986788568588423) D5 D6 D7 D10 D14 -error(0.002006705456917235505) D5 D6 D8 -error(0.0006697986788568588423) D5 D6 D9 -error(0.004005357180252827609) D5 D6 D9 D12 -error(0.0006697986788568588423) D5 D6 D9 D14 -error(0.0006697986788568588423) D5 D6 D10 D13 D14 -error(0.0006697986788568588423) D5 D7 D8 D11 L0 -error(0.002006705456917235505) D5 D7 D8 L0 -error(0.001338700097173320998) D5 D7 D10 D13 -error(0.0006697986788568588423) D5 D7 D10 D14 L0 -error(0.0006697986788568588423) D5 D7 D11 D14 L0 -error(0.001338700097173320998) D5 D8 D11 D12 -error(0.001338700097173320998) D5 D8 D11 D12 D13 -error(0.004005357180252827609) D5 D8 D11 D12 D14 L0 -error(0.002673815958446297981) D5 D8 D11 D14 -error(0.0006697986788568588423) D5 D8 D11 L0 -error(0.0006697986788568588423) D5 D8 D12 -error(0.0006697986788568588423) D5 D8 D12 D14 L0 -error(0.0006697986788568588423) D5 D8 D14 -error(0.003340032800510209492) D5 D8 L0 -error(0.004005357180252827609) D5 D9 -error(0.0006697986788568588423) D5 D9 D12 -error(0.0006697986788568588423) D5 D9 D12 D14 -error(0.001338700097173320998) D5 D10 -error(0.0006697986788568588423) D5 D10 D13 D14 L0 -error(0.006657753962803452177) D5 D11 -error(0.0006697986788568588423) D5 D11 D12 D13 D14 -error(0.0006697986788568588423) D5 D11 D12 D14 -error(0.0006697986788568588423) D5 D11 D13 D14 L0 -error(0.001338700097173320998) D5 D11 D14 L0 -error(0.001338700097173320998) D5 D14 L0 -error(0.004669790293214320931) D6 -error(0.004005357180252827609) D6 D7 -error(0.004669790293214320931) D6 D7 D8 -error(0.0006697986788568588423) D6 D7 D10 -error(0.001338700097173320998) D6 D7 D14 -error(0.004005357180252827609) D6 D8 -error(0.0006697986788568588423) D6 D8 D11 -error(0.0006697986788568588423) D6 D9 -error(0.0006697986788568588423) D6 D9 D10 -error(0.0006697986788568588423) D6 D9 D10 D11 D12 D13 -error(0.0006697986788568588423) D6 D9 D10 D11 D14 -error(0.0006697986788568588423) D6 D9 D10 D12 D13 -error(0.0006697986788568588423) D6 D9 D11 D12 -error(0.0006697986788568588423) D6 D9 D11 D14 -error(0.0006697986788568588423) D6 D9 D12 -error(0.0006697986788568588423) D6 D10 D13 -error(0.0006697986788568588423) D6 D11 D14 -error(0.006657753962803452177) D6 D12 -error(0.001338700097173320998) D6 D12 D13 -error(0.001338700097173320998) D6 D13 -error(0.001338700097173320998) D6 D13 D14 -error(0.005333333333333313206) D6 D14 -error(0.004005357180252827609) D7 D8 L0 -error(0.0006697986788568588423) D7 D10 D11 D13 D14 -error(0.0006697986788568588423) D7 D10 D11 L0 -error(0.004669790293214320931) D7 D10 D13 -error(0.001338700097173320998) D7 D10 L0 -error(0.001338700097173320998) D7 D12 -error(0.006657753962803452177) D7 D13 -error(0.001338700097173320998) D7 D13 D14 -error(0.001338700097173320998) D7 D14 L0 -error(0.007318633932043431753) D7 L0 -error(0.0006697986788568588423) D8 D11 D12 -error(0.0006697986788568588423) D8 D11 D12 D14 L0 -error(0.001338700097173320998) D8 D11 D14 -error(0.0006697986788568588423) D8 D11 L0 -error(0.001338700097173320998) D8 D12 -error(0.001338700097173320998) D8 D12 D13 -error(0.004005357180252827609) D8 D12 D14 L0 -error(0.006657753962803452177) D8 D14 -error(0.003340032800510209492) D8 L0 -error(0.0006697986788568588423) D9 -error(0.0006697986788568588423) D9 D10 -error(0.0006697986788568588423) D9 D10 D11 -error(0.0006697986788568588423) D9 D10 D11 D12 D13 D14 -error(0.0006697986788568588423) D9 D10 D12 D13 -error(0.0006697986788568588423) D9 D11 -error(0.0006697986788568588423) D9 D11 D12 D14 -error(0.0006697986788568588423) D9 D12 -error(0.004669790293214320931) D10 -error(0.0006697986788568588423) D10 D11 -error(0.0006697986788568588423) D10 D11 D13 D14 L0 -error(0.001338700097173320998) D10 D13 L0 -error(0.002006705456917235505) D11 -error(0.001338700097173320998) D11 D14 L0 -error(0.001338700097173320998) D12 -error(0.002006705456917235505) D12 D13 -error(0.002673815958446297981) D12 D13 D14 -error(0.002006705456917235505) D12 D14 -error(0.002006705456917235505) D13 D14 L0 -error(0.001338700097173320998) D13 L0 -error(0.001338700097173320998) D14 L0 -detector(0, 1, 0, 4) D0 -detector(1, 1, 0, 3) D1 -detector(2, 1, 0, 5) D2 -detector(0, 1, 0, 1) D3 -detector(1, 1, 0, 0) D4 -detector(2, 1, 0, 2) D5 -detector(0, 1, 0, 4) D6 -detector(1, 1, 0, 3) D7 -detector(2, 1, 0, 5) D8 -detector(0, 1, 0, 1) D9 -detector(1, 1, 0, 0) D10 -detector(2, 1, 0, 2) D11 -detector(0, 1, 0, 4) D12 -detector(1, 1, 0, 3) D13 -detector(2, 1, 0, 5) D14 -detector(0, 1, 1, 4) D15 -detector(1, 1, 1, 3) D16 -detector(2, 1, 1, 5) D17 diff --git a/libs/qec/python/tests/test_color_code.py b/libs/qec/python/tests/test_color_code.py index 25e4c7b3f..49b2f19c0 100644 --- a/libs/qec/python/tests/test_color_code.py +++ b/libs/qec/python/tests/test_color_code.py @@ -622,14 +622,17 @@ def merge(p, q): return sig -@pytest.mark.parametrize("basis", ["Z", "X"]) -def test_dem_matches_reference_golden(basis): +@pytest.mark.parametrize("d,rounds,basis", [(5, 5, "Z"), (5, 5, "X")]) +def test_dem_matches_reference_golden(d, rounds, basis): + # d=5 is the smallest distance exercising every structural element: bulk + # weight-6 plaquettes of all three colors plus every boundary type. stim_mod = pytest.importorskip("stim") - with open(os.path.join(_DATA_DIR, - f"superdense_golden_d3_r3_{basis}.dem")) as f: + with open( + os.path.join(_DATA_DIR, + f"superdense_golden_d{d}_r{rounds}_{basis}.dem")) as f: golden = f.read() golden = "\n".join(l for l in golden.splitlines() if not l.startswith("#")) - plan = SuperdensePlan(3, 3, basis) + plan = SuperdensePlan(d, rounds, basis) # An (empty) noise model must be passed or in-kernel apply_noise is a # silent no-op and the DEM comes back with zero error mechanisms. ours_text = cudaq.dem_from_kernel(superdense_memory, @@ -646,5 +649,55 @@ def test_dem_matches_reference_golden(basis): f"probability mismatch at {k}: ref={ref[k]}, ours={got[k]}") +_COORD_COLOR = {'red': 0., 'green': 1., 'blue': 2.} + + +@pytest.mark.parametrize("d", [3, 5, 7]) +@pytest.mark.parametrize("basis", ["Z", "X"]) +def test_detector_coords_contract(d, basis): + # Emission-order blocks: round-0 (P, memory basis), then per round r >= 1 + # an X block (P) followed by a Z block (P), then the final block (P, + # memory basis). Chromobius annotation: c = color + 3 for Z-checks. + rounds = 4 + plan = SuperdensePlan(d, rounds, basis) + P = plan.grid.num_plaquettes + assert len(plan.detector_coords) == len(plan.detectors) == 2 * P * rounds + + def block_is_z(det_idx): + if det_idx < P: + return basis == "Z" + if det_idx >= 2 * P * (rounds - 1) + P: + return basis == "Z" + return ((det_idx - P) // P) % 2 == 1 + + for i, (gr, gc, t, c) in enumerate(plan.detector_coords): + p = i % P + plaq = plan.grid.plaquettes[p] + assert (gr, gc) == tuple(map(float, plaq['grid_pos'])) + is_final = i >= 2 * P * (rounds - 1) + P + assert t == (1.0 if is_final else 0.0) + expected_c = _COORD_COLOR[plaq['color']] + (3.0 + if block_is_z(i) else 0.0) + assert c == expected_c + + +@pytest.mark.parametrize("basis,expected", [("Z", 0), ("X", 0)]) +def test_minimal_two_round_experiment(basis, expected): + # rounds=2 is the smallest experiment: round 0 plus the final round, with + # no bulk rounds in between. + dem = superdense_dem(3, 2, basis, p_cx=0.01) + plan = SuperdensePlan(3, 2, basis) + assert dem.num_detectors() == len(plan.detectors) == 12 + assert dem.num_error_mechanisms() > 0 + syndromes, data, logical = superdense_sample(3, + 2, + basis, + p_cx=0.0, + shots=30) + assert syndromes.shape == (30, 12) + assert not syndromes.any() + assert np.all(logical == expected) + + if __name__ == "__main__": pytest.main() From 653df41fc4a6f641b23960599633860af0daf9e1 Mon Sep 17 00:00:00 2001 From: kvmto Date: Thu, 9 Jul 2026 14:11:33 +0200 Subject: [PATCH 7/8] Remove the superdense memory-circuit machinery to keep this PR aligned with the structure of the existing code plugins; the plugin is used through the standard qec.sample_memory_circuit / dem_from_memory_circuit API. The geometry retains the pre-decoder mapping surface (CNN grid embedding, syndrome-to-grid indices, superdense plaquette labels) for upcoming work. Signed-off-by: kvmto --- .../cudaq_qec/plugins/codes/color_code.py | 778 ------------------ libs/qec/python/tests/test_color_code.py | 376 +-------- 2 files changed, 2 insertions(+), 1152 deletions(-) diff --git a/libs/qec/python/cudaq_qec/plugins/codes/color_code.py b/libs/qec/python/cudaq_qec/plugins/codes/color_code.py index c8c9b6cf1..f5b9d8549 100644 --- a/libs/qec/python/cudaq_qec/plugins/codes/color_code.py +++ b/libs/qec/python/cudaq_qec/plugins/codes/color_code.py @@ -446,180 +446,6 @@ def print_structure(self): ) print() - # ---------------------------------------------------------------------------------- - # Circuit-only physical layout (rectangular grid with blanks, including ancillas) - # ---------------------------------------------------------------------------------- - def get_circuit_physical_layout( - self, - *, - id_order: str = "rtl", - flip_rows: bool = False) -> Dict[int, Tuple[int, int]]: - """ - Return a *circuit-only* physical layout mapping qubit_id -> (r, c) on a rectangular grid. - - This layout is meant ONLY for reasoning about 2D nearest-neighbor connectivity constraints during - circuit construction. It does not affect the existing coordinate systems used elsewhere: - - `qubit_to_coord` / `coord_to_qubit` (triangular user coords) - - `qubit_to_grid` / `grid_to_qubit` (CNN rectangular embedding) - - Layout rules (as provided by user, generalized for odd distance d): - - Number of rows equals `self.n_rows = d + (d-1)//2`. - - Row lengths follow: 1, 3, 4, 5, 7, 8, 9, 11, 12, 13, ... (increments 2,1,1 repeating). - - Within each row, tokens alternate between data sites (D) and ancilla pairs (X,Z), and the X/Z - ancillas are adjacent horizontally with Z immediately to the left of X (left-to-right: Z then X). - - Row start offsets create a triangular envelope; the resulting rectangular width is (2*d - 1). - - Mapping convention: - - Data sites are assigned ids 0..num_data-1 using a deterministic per-row order controlled by `id_order`. - - Ancillas are assigned ids in two global blocks (all X first, then all Z), and within each block we also - use `id_order` per row. - - NOTE: Even though physically we place Z before X in each row, we still assign X ids first globally. - - Args: - id_order: - - "rtl": assign ids within each row from right-to-left. This matches the legacy triangle's upside-down - convention and makes the legacy schedule nearest-neighbor on this grid for odd distances tested. - - "ltr": assign ids within each row from left-to-right (natural scan order). - flip_rows: - - If True, return coordinates after reflecting the row index: (r, c) -> (n_rows - 1 - r, c). - This is useful when you want the same schedule embedded onto an up-facing vs down-facing triangle. - """ - d = int(self.distance) - width = 2 * d - 1 - n_rows = int(self.n_rows) - if id_order not in ("rtl", "ltr"): - raise ValueError("id_order must be 'rtl' or 'ltr'") - - # Row lengths: 1, 3, 4, 5, 7, 8, 9, 11, ... - def row_len(row_idx: int) -> int: - if row_idx == 0: - return 1 - g = row_idx // 3 - pos = row_idx % 3 - # pos 0: +1 from previous end of triple => 2g+5 for g>=1 (works out from pattern) - # easiest: build from recurrence: L0=1; delta pattern [2,1,1] repeating. - # but closed form below matches the observed sequence: - if pos == 0: - return 2 * g + 5 - if pos == 1: - return 2 * g + 3 - # pos == 2 - return 2 * g + 4 - - # More robust: generate lengths by recurrence to avoid mistakes. - lengths = [1] - deltas = [2, 1, 1] - for i in range(1, n_rows): - lengths.append(lengths[-1] + deltas[(i - 1) % 3]) - - # Row start offsets (column indices in [-d+1, d-1]) - starts = [0] - for i in range(1, n_rows): - # first delta=2 and first delta=1 both shift start left by 1; second delta=1 keeps start - starts.append(starts[-1] + (-1 if (i - 1) % 3 in (0, 1) else 0)) - - # Token generators per row type (Z then X) - def tokens_for_row(row_idx: int, L: int) -> List[str]: - if row_idx == 0: - return ["D"] - pos = row_idx % 3 - out: List[str] = [] - if pos == 0: - # start with "DD" - out.extend(["D", "D"]) - elif pos == 1: - # start with "D" - out.append("D") - else: # pos == 2 - # start with "ZX" - out.extend(["Z", "X"]) - - # Alternate between ZX and DD blocks. - # Determine next block type based on what we ended with. - next_block = "ZX" if (len(out) > 0 and out[-1] == "D") else "DD" - while len(out) < L: - if next_block == "ZX": - out.extend(["Z", "X"]) - next_block = "DD" - else: - out.extend(["D", "D"]) - next_block = "ZX" - return out[:L] - - # Collect token coordinates; assign ids afterward using `id_order`. - layout: Dict[int, Tuple[int, int]] = {} - d_positions: List[Tuple[int, int]] = [] - x_positions: List[Tuple[int, int]] = [] - z_positions: List[Tuple[int, int]] = [] - - for r in range(n_rows): - L = lengths[r] - start = starts[r] - toks = tokens_for_row(r, L) - for j, tok in enumerate(toks): - col = start + j - # shift to [0..width-1] - c = col + (d - 1) - if not (0 <= c < width): - raise AssertionError( - f"Physical layout column out of range: row={r} col={col} width={width}" - ) - if tok == "D": - d_positions.append((r, c)) - elif tok == "X": - x_positions.append((r, c)) - elif tok == "Z": - z_positions.append((r, c)) - else: - raise AssertionError(f"Unknown token {tok}") - - if len(d_positions) != int(self.num_data): - raise AssertionError( - f"Expected exactly num_data={self.num_data} data sites in physical layout, got {len(d_positions)}" - ) - - def _row_sort_key(rc: Tuple[int, int]) -> Tuple[int, int]: - rr, cc = rc - return (rr, -cc) if id_order == "rtl" else (rr, cc) - - # Assign data ids - data_id = 0 - for rc in sorted(d_positions, key=_row_sort_key): - layout[data_id] = rc - data_id += 1 - - # Assign ancilla ids: X first globally, then Z (regardless of left-to-right placement). - if len(x_positions) != int( - self.num_plaquettes) or len(z_positions) != int( - self.num_plaquettes): - raise AssertionError( - f"Expected exactly num_plaquettes={self.num_plaquettes} X and Z ancillas in physical layout, " - f"got X={len(x_positions)} Z={len(z_positions)}") - - x_id = int(self.num_data) - for (r, c) in sorted(x_positions, key=_row_sort_key): - layout[x_id] = (r, c) - x_id += 1 - - z_id = int(self.num_data + self.num_plaquettes) - for (r, c) in sorted(z_positions, key=_row_sort_key): - layout[z_id] = (r, c) - z_id += 1 - - if data_id != int(self.num_data) or x_id != int( - self.num_data + - self.num_plaquettes) or z_id != int(self.num_data + - 2 * self.num_plaquettes): - raise AssertionError( - "Physical layout did not assign all qubits: " - f"data={data_id}/{self.num_data} x={x_id - self.num_data}/{self.num_plaquettes} z={z_id - (self.num_data + self.num_plaquettes)}/{self.num_plaquettes}" - ) - - if flip_rows: - H = n_rows - return {q: (H - 1 - rc[0], rc[1]) for q, rc in layout.items()} - return layout - def superdense_plaquette(self, plaq_idx: int) -> Dict[str, int]: """ Return a canonical labeling for a plaquette for the superdense circuit. @@ -949,610 +775,6 @@ def get_num_z_stabilizers(self): return self.grid.num_plaquettes -# --------------------------------------------------------------------------- -# Superdense memory circuit -# -# Superdense memory circuit for the triangular color code. -# -# Each plaquette measures both its X and Z stabilizer in one round using a -# paired ancilla: the X-ancilla is prepared in |+>, the Z-ancilla in |0>, and -# an 8-CNOT-layer schedule entangles the pair (layers 1 and 8), couples each -# plaquette's data qubits into the pair with data as control (layers 2-4), and -# mirrors those couplings with the ancillas as control (layers 5-7). The -# mirrored half applies, per plaquette, an X on the data qubits coupled to the -# Z-ancilla conditioned on that ancilla's state; rather than measuring -# mid-circuit and feeding forward, the detectors carry the feedback-inlined -# parities, so the circuit stays straight-line Clifford. -# -# Label space used by this module: with N data qubits and P plaquettes, -# data qubits are 0..N-1, N + i is the X-ancilla of plaquette i, and -# N + P + i is the Z-ancilla of plaquette i (plaquette index order of -# :class:`ColorCodeGeometry`). -# -# Entry points: :func:`superdense_dem` (detector error model) and -# :func:`superdense_sample` (detector-ordered syndromes, final data readout, -# and logical parity). Both drive the :func:`superdense_memory` kernel, whose -# detector/observable annotations are emitted from a -# :class:`SuperdensePlan` — the host-side source of truth for the record -# layout, the per-detector measurement sets, and the detector coordinates. -# -# Decoder integration: `cudaq.detector` carries no coordinates, so the DEM -# returned by :func:`superdense_dem` is coordinate-free. -# ``SuperdensePlan(distance, rounds, basis).detector_coords`` supplies the -# 4-tuple ``(grid_row, grid_col, t, c)`` for each detector row, in emission -# order, with ``c = color + 3*basis`` (red/green/blue = 0/1/2; +3 for -# Z-checks) — the annotation convention Chromobius expects for color-code -# decoding. -# --------------------------------------------------------------------------- - - -def _rowmajor_cnot_layers(d: int) -> list[list[tuple[int, int]]]: - """ - The 8 CNOT layers of the superdense schedule in row-major inverted-triangle - numbering. - - The triangle is oriented with its widest row (d data qubits) on top, - narrowing to a single qubit at the bottom. - - Returns: - layers: length-8 list; each element is a list of (control, target) - pairs where - - data qubits: 0..num_data-1, row-major top-to-bottom - - ancillas: num_data..num_data+2*num_plaquettes-1, grouped as - (a1, a2) = (num_data + 2p, num_data + 2p + 1) with a1 the - X-ancilla and a2 the Z-ancilla of plaquette p - """ - d = int(d) - num_data = (3 * d * d + 1) // 4 - num_plaquettes = (3 * (d * d - 1)) // 8 - num_rows_data_qubits = (3 * d - 1) // 2 - - layers: list[list[tuple[int, int]]] = [] - - # tt=1..8 correspond to 8 layers - for tt in range(1, 9): - edges: list[tuple[int, int]] = [] - - if tt == 1 or tt == 8: - # CNOT between the two ancilla qubits: control |+> (a1), target |0> (a2) - index = num_data - for _ in range(num_plaquettes): - a1 = index - a2 = index + 1 - edges.append((a1, a2)) - index += 2 - - elif tt == 2: - # First sequence (data = control) - data_qubit_index = d - index_ancilla = num_data - cols = d - 1 - for rr in range(num_rows_data_qubits - 1): - if rr % 3 == 0: - for _ in range(cols): - edges.append((data_qubit_index, index_ancilla)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 1 - elif rr % 3 == 1: - for cc in range(cols): - edges.append((data_qubit_index, index_ancilla)) - data_qubit_index += 1 - if cc == cols - 1: - index_ancilla += 3 - else: - index_ancilla += 1 - else: # rr % 3 == 2 - for _ in range(cols): - edges.append((data_qubit_index, index_ancilla)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 1 - - elif tt == 3: - # Second sequence (data = control) - data_qubit_index = 0 - index_ancilla = num_data - cols = d - 1 - for rr in range(num_rows_data_qubits - 1): - if rr % 3 == 0: - for cc in range(cols): - edges.append((data_qubit_index, index_ancilla)) - index_ancilla += 1 - if cc == cols - 1: - data_qubit_index += 3 - else: - data_qubit_index += 1 - cols -= 1 - elif rr % 3 == 1: - for cc in range(cols): - edges.append((data_qubit_index, index_ancilla)) - data_qubit_index += 1 - if cc == cols - 1: - index_ancilla += 3 - else: - index_ancilla += 1 - else: # rr % 3 == 2 - for _ in range(cols): - edges.append((data_qubit_index, index_ancilla)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 1 - - elif tt == 4: - # Third sequence (data = control) - data_qubit_index = 1 - index_ancilla = num_data + d - 1 - cols = d - 1 - for rr in range(num_rows_data_qubits - 2): - if rr % 3 == 0: - for _ in range(cols): - edges.append((data_qubit_index, index_ancilla)) - data_qubit_index += 1 - index_ancilla += 1 - elif rr % 3 == 1: - for _ in range(cols): - edges.append((data_qubit_index, index_ancilla)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 2 - else: # rr % 3 == 2 - for cc in range(cols): - edges.append((data_qubit_index, index_ancilla)) - index_ancilla += 1 - if cc == cols - 1: - data_qubit_index += 3 - else: - data_qubit_index += 1 - - elif tt == 5: - # First sequence (data = target) => ancilla is control - data_qubit_index = d - index_ancilla = num_data - cols = d - 1 - for rr in range(num_rows_data_qubits - 1): - if rr % 3 == 0: - for _ in range(cols): - edges.append((index_ancilla, data_qubit_index)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 1 - elif rr % 3 == 1: - for cc in range(cols): - edges.append((index_ancilla, data_qubit_index)) - data_qubit_index += 1 - if cc == cols - 1: - index_ancilla += 3 - else: - index_ancilla += 1 - else: # rr % 3 == 2 - for _ in range(cols): - edges.append((index_ancilla, data_qubit_index)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 1 - - elif tt == 6: - # Second sequence (data = target) => ancilla is control - data_qubit_index = 0 - index_ancilla = num_data - cols = d - 1 - for rr in range(num_rows_data_qubits - 1): - if rr % 3 == 0: - for cc in range(cols): - edges.append((index_ancilla, data_qubit_index)) - index_ancilla += 1 - if cc == cols - 1: - data_qubit_index += 3 - else: - data_qubit_index += 1 - cols -= 1 - elif rr % 3 == 1: - for cc in range(cols): - edges.append((index_ancilla, data_qubit_index)) - data_qubit_index += 1 - if cc == cols - 1: - index_ancilla += 3 - else: - index_ancilla += 1 - else: # rr % 3 == 2 - for _ in range(cols): - edges.append((index_ancilla, data_qubit_index)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 1 - - else: # tt == 7 - # Third sequence (data = target) => ancilla is control - data_qubit_index = 1 - index_ancilla = num_data + d - 1 - cols = d - 1 - for rr in range(num_rows_data_qubits - 2): - if rr % 3 == 0: - for _ in range(cols): - edges.append((index_ancilla, data_qubit_index)) - data_qubit_index += 1 - index_ancilla += 1 - elif rr % 3 == 1: - for _ in range(cols): - edges.append((index_ancilla, data_qubit_index)) - data_qubit_index += 1 - index_ancilla += 1 - cols -= 2 - else: # rr % 3 == 2 - for cc in range(cols): - edges.append((index_ancilla, data_qubit_index)) - index_ancilla += 1 - if cc == cols - 1: - data_qubit_index += 3 - else: - data_qubit_index += 1 - - layers.append(sorted(edges)) - - return layers - - -def _rowmajor_to_unified(grid: ColorCodeGeometry) -> dict[int, int]: - """ - Bijection from the row-major inverted-triangle qubit numbering of - :func:`_rowmajor_cnot_layers` to the unified label space. - - Data qubits: the grid's coordinates put row 0 at the top with rows - decreasing (more negative) downward, so sorting data ids by (row, col) - ascending enumerates them bottom-to-top, left-to-right — exactly the - row-major order of the inverted triangle (widest row first). - - Ancillas: plaquettes are matched by their data-qubit support sets (the - data endpoints coupled to an ancilla pair across all layers), then - (a1, a2) = (num_data + 2p, num_data + 2p + 1) maps to - (N + i, N + P + i) for the matching plaquette index i. - """ - N = int(grid.num_data) - P = int(grid.num_plaquettes) - - ordered_data = sorted( - range(N), - key=lambda q: (grid.qubit_to_coord[q][0], grid.qubit_to_coord[q][1])) - data_to_rowmajor = {q: i for i, q in enumerate(ordered_data)} - - layers = _rowmajor_cnot_layers(grid.distance) - - # Support set (in row-major data ids) of each row-major plaquette. - support_to_plaq = {} - for p in range(P): - a1 = N + 2 * p - a2 = N + 2 * p + 1 - ds = set() - for layer in layers: - for c, t in layer: - if c < N and t in (a1, a2): - ds.add(c) - if c in (a1, a2) and t < N: - ds.add(t) - support_to_plaq[tuple(sorted(ds))] = p - - mapping = {i: q for q, i in data_to_rowmajor.items()} - for i, plaq in enumerate(grid.plaquettes): - key = tuple(sorted(data_to_rowmajor[q] for q in plaq['data_qubits'])) - p = support_to_plaq.get(key) - if p is None: - raise ValueError( - f"Plaquette {i} (data qubits {plaq['data_qubits']}) has no " - f"support-set match in the schedule") - mapping[N + 2 * p] = N + i - mapping[N + 2 * p + 1] = N + P + i - return mapping - - -def superdense_cnot_layers( - grid: ColorCodeGeometry) -> list[list[tuple[int, int]]]: - """Eight CNOT layers of the paired-ancilla superdense schedule. - - Unified label space: 0..N-1 data qubit ids, N+i the X-ancilla and - N+P+i the Z-ancilla of plaquette i. Layers 1 and 8 entangle each - plaquette's ancilla pair; layers 2-4 couple data (control) into the - pair; layers 5-7 apply the mirrored ancilla-controlled CNOTs. - """ - mapping = _rowmajor_to_unified(grid) - return [ - sorted((mapping[c], mapping[t]) - for c, t in layer) - for layer in _rowmajor_cnot_layers(grid.distance) - ] - - -def z_side_data(grid: ColorCodeGeometry) -> list[list[int]]: - """Per plaquette, the data qubits coupled to its Z-ancilla by the - schedule; a conditional X on exactly these qubits is the byproduct the - Z-ancilla readout heralds.""" - layers = superdense_cnot_layers(grid) - N, P = grid.num_data, grid.num_plaquettes - out = [set() for _ in range(P)] - for li in (1, 2, 3): - for c, t in layers[li]: - if t >= N + P: - out[t - N - P].add(c) - return [sorted(s) for s in out] - - -_COLOR_IDX = {'red': 0, 'green': 1, 'blue': 2} - - -class SuperdensePlan: - """Detector/observable layout of the superdense memory circuit. - - Record indexing: round r contributes records [2*P*r, 2*P*r + P) for the - Z-ancillas (plaquette order) then [2*P*r + P, 2*P*(r+1)) for the - X-ancillas; the final transversal data measurement occupies - [2*P*rounds, 2*P*rounds + N) in data-qubit order. - - The Z-ancilla readouts herald conditional-X byproducts on their - schedule-side data qubits; detectors and the Z-basis observable carry - the absorbed correction records instead of physical feedback gates. - """ - - def __init__(self, distance, rounds, basis): - if basis not in ('X', 'Z'): - raise ValueError("basis must be 'X' or 'Z'") - if rounds < 2: - raise ValueError("rounds must be >= 2") - self.grid = ColorCodeGeometry(distance) - self.rounds = rounds - self.basis = basis - grid = self.grid - P, N = grid.num_plaquettes, grid.num_data - self.num_records = 2 * P * rounds + N - - zside = z_side_data(grid) - - def F(support): - s = set(support) - return [a for a in range(P) if len(set(zside[a]) & s) % 2 == 1] - - self.prev_sets = [ - sorted({p} ^ set(F(grid.plaquettes[p]['data_qubits']))) - for p in range(P) - ] - self.obs_plaqs = sorted(F(grid.logical_qubits)) - - Z = lambda p, r: 2 * P * r + p - X = lambda p, r: 2 * P * r + P + p - D = lambda q: 2 * P * rounds + q - - def coords(p, t, z_type): - gp = grid.plaquettes[p]['grid_pos'] - c = _COLOR_IDX[grid.plaquettes[p]['color']] + (3 if z_type else 0) - return (float(gp[0]), float(gp[1]), float(t), float(c)) - - dets, cs = [], [] - for p in range(P): - if basis == 'Z': - dets.append(frozenset({Z(p, 0)})) - cs.append(coords(p, 0, True)) - else: - dets.append(frozenset({X(p, 0)})) - cs.append(coords(p, 0, False)) - for r in range(1, rounds): - for p in range(P): - dets.append(frozenset({X(p, r), X(p, r - 1)})) - cs.append(coords(p, 0, False)) - for p in range(P): - dets.append( - frozenset({Z(p, r)}) | - {Z(a, r - 1) for a in self.prev_sets[p]}) - cs.append(coords(p, 0, True)) - for p in range(P): - supp = grid.plaquettes[p]['data_qubits'] - if basis == 'Z': - dets.append( - frozenset(D(q) for q in supp) | - {Z(a, rounds - 1) for a in self.prev_sets[p]}) - cs.append(coords(p, 1, True)) - else: - dets.append( - frozenset({X(p, rounds - 1)}) | {D(q) for q in supp}) - cs.append(coords(p, 1, False)) - self.detectors = dets - self.detector_coords = cs - - if basis == 'Z': - obs = {D(q) for q in grid.logical_qubits} - for r in range(rounds): - obs ^= {Z(a, r) for a in self.obs_plaqs} - self.observable = frozenset(obs) - else: - self.observable = frozenset(D(q) for q in range(N)) - - def detector_bits(self, measurements): - m = np.asarray(measurements, dtype=np.uint8) - out = np.zeros((m.shape[0], len(self.detectors)), dtype=np.uint8) - for j, s in enumerate(self.detectors): - out[:, j] = np.bitwise_xor.reduce(m[:, sorted(s)], axis=1) - return out - - def observable_bits(self, measurements): - m = np.asarray(measurements, dtype=np.uint8) - return np.bitwise_xor.reduce(m[:, sorted(self.observable)], axis=1) - - -def _kernel_args(plan, p_cx): - if p_cx < 0: - raise ValueError(f"p_cx must be non-negative, got {p_cx}") - grid = plan.grid - N, P, R = grid.num_data, grid.num_plaquettes, plan.rounds - layers = superdense_cnot_layers(grid) - sched = [q for layer in layers for e in layer for q in e] - sched_off = [0] - for layer in layers: - sched_off.append(sched_off[-1] + 2 * len(layer)) - # prev_sets and final supports, padded to fixed strides - ps_stride = max(len(s) for s in plan.prev_sets) - ps_flat, ps_cnt = [], [] - for s in plan.prev_sets: - ps_cnt.append(len(s)) - ps_flat.extend(s + [0] * (ps_stride - len(s))) - supp_stride = 6 - supp_flat, supp_cnt = [], [] - for p in range(P): - supp = grid.plaquettes[p]['data_qubits'] - supp_cnt.append(len(supp)) - supp_flat.extend(list(supp) + [0] * (supp_stride - len(supp))) - obs = sorted(plan.obs_plaqs) - logical = list(grid.logical_qubits) - return (N, P, R, 1 if plan.basis == 'Z' else 0, float(p_cx), sched, - sched_off, ps_flat, ps_cnt, ps_stride, supp_flat, supp_cnt, - supp_stride, obs, logical) - - -@cudaq.kernel -def superdense_memory(N: int, P: int, R: int, z_basis: int, p_cx: float, - sched: list[int], sched_off: list[int], - ps_flat: list[int], ps_cnt: list[int], ps_stride: int, - supp_flat: list[int], supp_cnt: list[int], - supp_stride: int, obs: list[int], logical: list[int]): - # One register indexed directly by the unified labels: q[0..N) data, - # q[N..N+P) X-ancillas, q[N+P..N+2P) Z-ancillas (plaquette order), so - # the sched entries need no decoding. Per round the Z-ancillas are - # measured before the X-ancillas and the final data measurement comes - # last: exactly the SuperdensePlan record layout. - q = cudaq.qvector(N + 2 * P) - - if z_basis == 0: - for i in range(N): - h(q[i]) - - # Round 0. Fresh qubits start in |0>, so the per-round ancilla resets - # are elided; only the X-ancilla |+> prep is needed. - for i in range(P): - h(q[N + i]) - for li in range(8): - for k in range(sched_off[li], sched_off[li + 1], 2): - x.ctrl(q[sched[k]], q[sched[k + 1]]) - # Perfect-final-round convention: noise on every schedule CX of - # every round except the last. - if p_cx > 0.0 and R > 1: - cudaq.apply_noise(cudaq.Depolarization2, p_cx, q[sched[k]], - q[sched[k + 1]]) - zprev = mz(q[N + P:N + 2 * P]) - if z_basis == 1: - # Z-basis observable: the obs_plaqs Z-ancilla records of every - # round accumulate into L0 (inlined feed-forward byproduct). - for j in range(len(obs)): - cudaq.logical_observable(zprev[obs[j]]) - for i in range(P): - h(q[N + i]) - xprev = mz(q[N:N + P]) - # Round-0 detectors: memory-basis single-record checks. - if z_basis == 1: - for p in range(P): - cudaq.detector(zprev[p]) - else: - for p in range(P): - cudaq.detector(xprev[p]) - - for r in range(1, R): - for i in range(P): - reset(q[N + i]) - h(q[N + i]) - reset(q[N + P + i]) - for li in range(8): - for k in range(sched_off[li], sched_off[li + 1], 2): - x.ctrl(q[sched[k]], q[sched[k + 1]]) - if p_cx > 0.0 and r < R - 1: - cudaq.apply_noise(cudaq.Depolarization2, p_cx, q[sched[k]], - q[sched[k + 1]]) - zcurr = mz(q[N + P:N + 2 * P]) - if z_basis == 1: - for j in range(len(obs)): - cudaq.logical_observable(zcurr[obs[j]]) - for i in range(P): - h(q[N + i]) - xcurr = mz(q[N:N + P]) - for p in range(P): - cudaq.detector(xcurr[p], xprev[p]) - for p in range(P): - # Z comparison detector: current Z record against the previous - # round's prev_set records (plaquette indices into zprev). - if ps_cnt[p] == 0: - cudaq.detector(zcurr[p]) - else: - psel = [ - zprev[ps_flat[p * ps_stride + j]] for j in range(ps_cnt[p]) - ] - cudaq.detector(zcurr[p], psel) - zprev = zcurr - xprev = xcurr - - if z_basis == 0: - for i in range(N): - h(q[i]) - dm = mz(q[0:N]) - for p in range(P): - dsel = [dm[supp_flat[p * supp_stride + j]] for j in range(supp_cnt[p])] - if z_basis == 1: - if ps_cnt[p] == 0: - cudaq.detector(dsel) - else: - psel = [ - zprev[ps_flat[p * ps_stride + j]] for j in range(ps_cnt[p]) - ] - cudaq.detector(dsel, psel) - else: - cudaq.detector(xprev[p], dsel) - if z_basis == 1: - for j in range(len(logical)): - cudaq.logical_observable(dm[logical[j]]) - else: - cudaq.logical_observable(dm) - - -def superdense_dem(distance, rounds, basis, p_cx): - """Detector error model of the superdense memory circuit. - - The returned model's detector rows follow the plan's emission order; - chromobius coordinates for each row are available from - SuperdensePlan(distance, rounds, basis).detector_coords. - """ - plan = SuperdensePlan(distance, rounds, basis) - # An (empty) noise model must be passed or in-kernel apply_noise is a - # silent no-op and the DEM comes back with zero error mechanisms. - text = cudaq.dem_from_kernel(superdense_memory, - *_kernel_args(plan, p_cx), - noise_model=cudaq.NoiseModel()) - return qec.dem_from_stim_text(text) - - -def superdense_sample(distance, rounds, basis, p_cx, shots): - """Sample the superdense memory circuit. - - Returns: - (syndromes, data, logical): syndromes is a (shots, 2*P*rounds) uint8 - array of detector bits in plan emission order; data is a (shots, N) - array of raw final data-qubit bits; logical is a (shots,) array of - observable parity. - """ - plan = SuperdensePlan(distance, rounds, basis) - # Same activation requirement as in superdense_dem: without a noise - # model argument the in-kernel apply_noise calls do nothing. - res = cudaq.sample(superdense_memory, - *_kernel_args(plan, p_cx), - shots_count=shots, - explicit_measurements=True, - noise_model=cudaq.NoiseModel()) - # get_sequential_data() yields one '0'/'1' string per shot in record - # order; convert per character (np.array on the raw strings would parse - # each whole string as a single number). - m = np.array([[c == '1' for c in s] for s in res.get_sequential_data()], - dtype=np.uint8) - if m.shape[1] != plan.num_records: - raise RuntimeError( - f"expected {plan.num_records} measurement records per shot, " - f"got {m.shape[1]}") - N = plan.grid.num_data - return (plan.detector_bits(m), m[:, -N:], plan.observable_bits(m)) - - if __name__ == "__main__": for d in [3, 5, 7]: print("=" * 60) diff --git a/libs/qec/python/tests/test_color_code.py b/libs/qec/python/tests/test_color_code.py index 49b2f19c0..2cfd147db 100644 --- a/libs/qec/python/tests/test_color_code.py +++ b/libs/qec/python/tests/test_color_code.py @@ -10,11 +10,7 @@ import cudaq import cudaq_qec as qec -import os - -from cudaq_qec.plugins.codes.color_code import ( - ColorCodeGeometry, SuperdensePlan, superdense_cnot_layers, z_side_data, - superdense_dem, superdense_sample, superdense_memory, _kernel_args) +from cudaq_qec.plugins.codes.color_code import ColorCodeGeometry @pytest.fixture(scope="module", autouse=True) @@ -74,7 +70,7 @@ def support_matrix(grid): return S -@pytest.mark.parametrize("d", [3, 5, 7, 9, 11, 13]) +@pytest.mark.parametrize("d", [3, 5, 7, 9]) def test_geometry_counts(d): grid = ColorCodeGeometry(d) assert grid.num_data == (3 * d * d + 1) // 4 @@ -195,39 +191,6 @@ def test_get_syndrome_grid_indices(d): assert len(set(idx.tolist())) == len(idx) -@pytest.mark.parametrize("d", [3, 5, 7]) -@pytest.mark.parametrize("id_order", ["rtl", "ltr"]) -@pytest.mark.parametrize("flip_rows", [False, True]) -def test_circuit_physical_layout(d, id_order, flip_rows): - grid = ColorCodeGeometry(d) - layout = grid.get_circuit_physical_layout(id_order=id_order, - flip_rows=flip_rows) - n_total = grid.num_data + 2 * grid.num_plaquettes - # Every qubit id placed exactly once, on distinct sites, inside the - # (n_rows) x (2d-1) rectangle. - assert set(layout.keys()) == set(range(n_total)) - coords = list(layout.values()) - assert len(set(coords)) == len(coords) - for r, c in coords: - assert 0 <= r < grid.n_rows - assert 0 <= c < 2 * d - 1 - - -def test_circuit_physical_layout_flip_rows_is_reflection(): - grid = ColorCodeGeometry(5) - base = grid.get_circuit_physical_layout() - flipped = grid.get_circuit_physical_layout(flip_rows=True) - H = grid.n_rows - for q, (r, c) in base.items(): - assert flipped[q] == (H - 1 - r, c) - - -def test_circuit_physical_layout_rejects_bad_id_order(): - grid = ColorCodeGeometry(3) - with pytest.raises(ValueError, match="id_order"): - grid.get_circuit_physical_layout(id_order="bogus") - - @pytest.mark.parametrize("d", [3, 5]) def test_superdense_plaquette_labels(d): grid = ColorCodeGeometry(d) @@ -267,20 +230,6 @@ def test_print_structure_smoke(capsys): _plaquette_pauli_words) -@pytest.mark.parametrize("d", [3, 5, 7]) -def test_plaquette_pauli_words(d): - grid = ColorCodeGeometry(d) - x_words, z_words = _plaquette_pauli_words(grid) - assert len(x_words) == len(z_words) == grid.num_plaquettes - for x_word, z_word, plaq in zip(x_words, z_words, grid.plaquettes): - assert len(x_word) == len(z_word) == grid.num_data - support = set(plaq['data_qubits']) - assert {i for i, ch in enumerate(x_word) if ch == 'X'} == support - assert set(x_word) <= {'I', 'X'} - assert {i for i, ch in enumerate(z_word) if ch == 'Z'} == support - assert set(z_word) <= {'I', 'Z'} - - def test_plaquette_pauli_words_d3_explicit(): # d=3 plaquettes in grid-sorted order: green [0,1,2,3] (maps to D0), # red [1,3,5,6] (maps to D1), blue [2,3,4,5] (maps to D3). @@ -290,16 +239,6 @@ def test_plaquette_pauli_words_d3_explicit(): assert x_words == ["XXXXIII", "IXIXIXX", "IIXXXXI"] -@pytest.mark.parametrize("d", [3, 5, 7]) -def test_logical_pauli_words(d): - grid = ColorCodeGeometry(d) - x_word, z_word = _logical_pauli_words(grid) - support = set(grid.logical_qubits) - assert {i for i, ch in enumerate(x_word) if ch == 'X'} == support - assert {i for i, ch in enumerate(z_word) if ch == 'Z'} == support - assert len(x_word) == len(z_word) == grid.num_data - - def test_logical_pauli_words_d3_explicit(): # d=3 bottom edge is qubits 4,5,6 — same as the Steane-style tail. grid = ColorCodeGeometry(3) @@ -388,316 +327,5 @@ def test_plugin_stabilizers_list(): } -# --------------------------------------------------------------------------- -# Superdense memory circuit -# --------------------------------------------------------------------------- - - -def _compass_z_side(grid, p_idx): - # Independent oracle for the Z-ancilla coupling set, from the superdense - # compass labels: bulk -> {q4,q5,q6}; boundary green -> {q1,q2,q6}; - # boundary red -> {q5}; boundary blue -> {q5,q6}. - labels = grid.superdense_plaquette(p_idx) - plaq = grid.plaquettes[p_idx] - if plaq['weight'] == 6: - keys = ['q4', 'q5', 'q6'] - elif plaq['color'] == 'green': - keys = ['q1', 'q2', 'q6'] - elif plaq['color'] == 'red': - keys = ['q5'] - else: - keys = ['q5', 'q6'] - return sorted(labels[k] for k in keys) - - -@pytest.mark.parametrize("d", [3, 5, 7]) -def test_schedule_shape_and_disjointness(d): - grid = ColorCodeGeometry(d) - N, P = grid.num_data, grid.num_plaquettes - layers = superdense_cnot_layers(grid) - assert len(layers) == 8 - # Layers 1 and 8: pure X-ancilla -> Z-ancilla of the same plaquette. - for li in (0, 7): - assert sorted(layers[li]) == [(N + i, N + P + i) for i in range(P)] - # Every layer's endpoints are disjoint (parallel-executable). - for layer in layers: - seen = [q for e in layer for q in e] - assert len(seen) == len(set(seen)) - # Layers 2-4: data is control; layers 5-7: data is target. - for li in (1, 2, 3): - assert all(c < N and t >= N for c, t in layers[li]) - for li in (4, 5, 6): - assert all(c >= N and t < N for c, t in layers[li]) - # Mirror property: layers 5-7 contain exactly the reversed edges of 2-4. - fwd = {frozenset(e) for li in (1, 2, 3) for e in layers[li]} - bwd = {frozenset(e) for li in (4, 5, 6) for e in layers[li]} - assert fwd == bwd - # Every data-ancilla edge stays inside its plaquette's support. - for li in (1, 2, 3, 4, 5, 6): - for c, t in layers[li]: - dq, anc = (c, t) if c < N else (t, c) - p_idx = (anc - N) % P - assert dq in grid.plaquettes[p_idx]['data_qubits'] - - -@pytest.mark.parametrize("d", [3, 5, 7]) -def test_z_side_data_matches_compass_rule(d): - grid = ColorCodeGeometry(d) - zs = z_side_data(grid) - assert len(zs) == grid.num_plaquettes - for p_idx in range(grid.num_plaquettes): - assert zs[p_idx] == _compass_z_side(grid, p_idx) - - -@pytest.mark.parametrize("d", [3, 5, 7]) -def test_every_plaquette_qubit_coupled_exactly_once_per_side(d): - # Each data qubit of a plaquette couples to exactly one of the pair - # (a1 or a2), once on the forward side and once on the mirror side. - grid = ColorCodeGeometry(d) - N, P = grid.num_data, grid.num_plaquettes - layers = superdense_cnot_layers(grid) - for p_idx, plaq in enumerate(grid.plaquettes): - anc_pair = {N + p_idx, N + P + p_idx} - fwd = [e for li in (1, 2, 3) for e in layers[li] if (e[1] in anc_pair)] - touched = sorted(e[0] for e in fwd) - assert touched == sorted(plaq['data_qubits']) - - -# Ground truth: detector sets of the reference superdense construction after -# stim's with_inlined_feedback(), d=3, 3 rounds. -EXPECTED_D3_R3_Z = { - "detectors": [((0.0, 1.0, 0.0, 4.0), [0]), ((1.0, 1.0, 0.0, 3.0), [1]), - ((2.0, 1.0, 0.0, 5.0), [2]), ((0.0, 1.0, 0.0, 1.0), [3, 9]), - ((1.0, 1.0, 0.0, 0.0), [4, 10]), - ((2.0, 1.0, 0.0, 2.0), [5, 11]), - ((0.0, 1.0, 0.0, 4.0), [2, 6]), ((1.0, 1.0, 0.0, 3.0), [7]), - ((2.0, 1.0, 0.0, 5.0), [0, 2, 8]), - ((0.0, 1.0, 0.0, 1.0), [9, 15]), - ((1.0, 1.0, 0.0, 0.0), [10, 16]), - ((2.0, 1.0, 0.0, 2.0), [11, 17]), - ((0.0, 1.0, 0.0, 4.0), [8, 12]), ((1.0, 1.0, 0.0, 3.0), [13]), - ((2.0, 1.0, 0.0, 5.0), [6, 8, 14]), - ((0.0, 1.0, 1.0, 4.0), [14, 18, 19, 20, 21]), - ((1.0, 1.0, 1.0, 3.0), [19, 21, 23, 24]), - ((2.0, 1.0, 1.0, 5.0), [12, 14, 20, 21, 22, 23])], - "observable": [1, 2, 7, 8, 13, 14, 22, 23, 24], -} - -EXPECTED_D3_R3_X = { - "detectors": [((0.0, 1.0, 0.0, 1.0), [3]), ((1.0, 1.0, 0.0, 0.0), [4]), - ((2.0, 1.0, 0.0, 2.0), [5]), ((0.0, 1.0, 0.0, 1.0), [3, 9]), - ((1.0, 1.0, 0.0, 0.0), [4, 10]), - ((2.0, 1.0, 0.0, 2.0), [5, 11]), - ((0.0, 1.0, 0.0, 4.0), [2, 6]), ((1.0, 1.0, 0.0, 3.0), [7]), - ((2.0, 1.0, 0.0, 5.0), [0, 2, 8]), - ((0.0, 1.0, 0.0, 1.0), [9, 15]), - ((1.0, 1.0, 0.0, 0.0), [10, 16]), - ((2.0, 1.0, 0.0, 2.0), [11, 17]), - ((0.0, 1.0, 0.0, 4.0), [8, 12]), ((1.0, 1.0, 0.0, 3.0), [13]), - ((2.0, 1.0, 0.0, 5.0), [6, 8, 14]), - ((0.0, 1.0, 1.0, 1.0), [15, 18, 19, 20, 21]), - ((1.0, 1.0, 1.0, 0.0), [16, 19, 21, 23, 24]), - ((2.0, 1.0, 1.0, 2.0), [17, 20, 21, 22, 23])], - "observable": [18, 19, 20, 21, 22, 23, 24], -} - - -@pytest.mark.parametrize("basis,expected", [("Z", EXPECTED_D3_R3_Z), - ("X", EXPECTED_D3_R3_X)]) -def test_plan_matches_reference_d3_r3(basis, expected): - plan = SuperdensePlan(3, 3, basis) - got = [(tuple(c), sorted(s)) - for c, s in zip(plan.detector_coords, plan.detectors)] - assert got == expected["detectors"] - assert sorted(plan.observable) == expected["observable"] - - -@pytest.mark.parametrize("d,rounds,basis", - [(3, 3, "Z"), (3, 4, "X"), (5, 3, "Z"), (5, 4, "X"), - (7, 5, "Z"), (7, 5, "X")]) -def test_plan_structure(d, rounds, basis): - plan = SuperdensePlan(d, rounds, basis) - P = plan.grid.num_plaquettes - N = plan.grid.num_data - assert len(plan.detectors) == 2 * P * rounds - assert len(plan.detector_coords) == len(plan.detectors) - assert plan.num_records == 2 * P * rounds + N - for s in plan.detectors: - assert all(0 <= i < plan.num_records for i in s) - # Round-0 detectors are single-record, memory basis. - for p in range(P): - (rec,) = plan.detectors[p] - assert rec == (p if basis == "Z" else P + p) - - -def test_detector_bits_xor(): - plan = SuperdensePlan(3, 3, "Z") - m = np.zeros((2, plan.num_records), dtype=np.uint8) - # Flip exactly ONE record of detector 5 in shot 1: precisely the - # detectors containing that record must fire. - rec = sorted(plan.detectors[5])[0] - m[1, rec] = 1 - bits = plan.detector_bits(m) - assert bits.shape == (2, len(plan.detectors)) - assert not bits[0].any() - expected = {j for j, s in enumerate(plan.detectors) if rec in s} - assert set(np.flatnonzero(bits[1]).tolist()) == expected - assert 5 in expected - - -@pytest.mark.parametrize("d,rounds,basis", [(3, 3, "Z"), (3, 3, "X"), - (5, 3, "Z"), (5, 3, "X")]) -def test_dem_construction_succeeds(d, rounds, basis): - # stim validates every declared detector is deterministic; passing this - # call at all is the determinism proof for the inlined parities. - dem = superdense_dem(d, rounds, basis, p_cx=0.01) - plan = SuperdensePlan(d, rounds, basis) - assert dem.num_detectors() == len(plan.detectors) - assert dem.num_observables() == 1 - assert dem.num_error_mechanisms() > 0 - assert dem.detector_error_matrix.shape[0] == len(plan.detectors) - - -@pytest.mark.parametrize("basis,expected", [("Z", 0), ("X", 0)]) -def test_noiseless_sampling_deterministic(basis, expected): - syndromes, data, logical = superdense_sample(3, - 3, - basis, - p_cx=0.0, - shots=50) - assert syndromes.shape == (50, 18) - assert data.shape == (50, 7) - assert not syndromes.any() - assert np.all(logical == expected) - - -def test_noisy_sampling_fires_detectors(): - syndromes, _, _ = superdense_sample(3, 4, "Z", p_cx=0.05, shots=200) - assert syndromes.any() - # No detector column should fire in (nearly) all shots — that would - # indicate a broken parity rather than noise. - assert syndromes.mean(axis=0).max() < 0.75 - - -def test_decoding_reduces_logical_errors(): - cudaq.set_random_seed(13) - d, rounds, p = 3, 4, 0.01 - dem = superdense_dem(d, rounds, "Z", p_cx=p) - syndromes, _, logical = superdense_sample(d, - rounds, - "Z", - p_cx=p, - shots=1000) - decoder = qec.get_decoder('single_error_lut', dem.detector_error_matrix) - dr = decoder.decode_batch(syndromes) - err = np.asarray(dr.result, dtype=np.uint8) - pred = ((dem.observables_flips_matrix @ err.T) % 2).flatten() - n_without = int(logical.sum()) - n_with = int((pred ^ logical).sum()) - print(f"logical errors without decoding: {n_without}, with: {n_with}") - assert n_with < n_without - - -_DATA_DIR = os.path.join(os.path.dirname(__file__), "data") - - -def _dem_signature(dem_text, stim_mod): - # Canonical multiset {(detectors, observables) -> merged probability}. - def merge(p, q): - return p + q - 2.0 * p * q - - sig = {} - for inst in stim_mod.DetectorErrorModel(dem_text).flattened(): - if inst.type != "error": - continue - prob = inst.args_copy()[0] - dets, obss = [], [] - for t in inst.targets_copy(): - if t.is_relative_detector_id(): - dets.append(t.val) - elif t.is_logical_observable_id(): - obss.append(t.val) - key = (tuple(sorted(dets)), tuple(sorted(obss))) - sig[key] = merge(sig[key], prob) if key in sig else prob - return sig - - -@pytest.mark.parametrize("d,rounds,basis", [(5, 5, "Z"), (5, 5, "X")]) -def test_dem_matches_reference_golden(d, rounds, basis): - # d=5 is the smallest distance exercising every structural element: bulk - # weight-6 plaquettes of all three colors plus every boundary type. - stim_mod = pytest.importorskip("stim") - with open( - os.path.join(_DATA_DIR, - f"superdense_golden_d{d}_r{rounds}_{basis}.dem")) as f: - golden = f.read() - golden = "\n".join(l for l in golden.splitlines() if not l.startswith("#")) - plan = SuperdensePlan(d, rounds, basis) - # An (empty) noise model must be passed or in-kernel apply_noise is a - # silent no-op and the DEM comes back with zero error mechanisms. - ours_text = cudaq.dem_from_kernel(superdense_memory, - *_kernel_args(plan, 0.01), - noise_model=cudaq.NoiseModel()) - ref = _dem_signature(golden, stim_mod) - got = _dem_signature(ours_text, stim_mod) - assert set(ref) == set(got), ( - f"error-mechanism signatures differ: ref-only " - f"{sorted(set(ref) - set(got))[:5]}, ours-only " - f"{sorted(set(got) - set(ref))[:5]}") - for k in ref: - assert np.isclose(ref[k], got[k], atol=1e-6, rtol=1e-4), ( - f"probability mismatch at {k}: ref={ref[k]}, ours={got[k]}") - - -_COORD_COLOR = {'red': 0., 'green': 1., 'blue': 2.} - - -@pytest.mark.parametrize("d", [3, 5, 7]) -@pytest.mark.parametrize("basis", ["Z", "X"]) -def test_detector_coords_contract(d, basis): - # Emission-order blocks: round-0 (P, memory basis), then per round r >= 1 - # an X block (P) followed by a Z block (P), then the final block (P, - # memory basis). Chromobius annotation: c = color + 3 for Z-checks. - rounds = 4 - plan = SuperdensePlan(d, rounds, basis) - P = plan.grid.num_plaquettes - assert len(plan.detector_coords) == len(plan.detectors) == 2 * P * rounds - - def block_is_z(det_idx): - if det_idx < P: - return basis == "Z" - if det_idx >= 2 * P * (rounds - 1) + P: - return basis == "Z" - return ((det_idx - P) // P) % 2 == 1 - - for i, (gr, gc, t, c) in enumerate(plan.detector_coords): - p = i % P - plaq = plan.grid.plaquettes[p] - assert (gr, gc) == tuple(map(float, plaq['grid_pos'])) - is_final = i >= 2 * P * (rounds - 1) + P - assert t == (1.0 if is_final else 0.0) - expected_c = _COORD_COLOR[plaq['color']] + (3.0 - if block_is_z(i) else 0.0) - assert c == expected_c - - -@pytest.mark.parametrize("basis,expected", [("Z", 0), ("X", 0)]) -def test_minimal_two_round_experiment(basis, expected): - # rounds=2 is the smallest experiment: round 0 plus the final round, with - # no bulk rounds in between. - dem = superdense_dem(3, 2, basis, p_cx=0.01) - plan = SuperdensePlan(3, 2, basis) - assert dem.num_detectors() == len(plan.detectors) == 12 - assert dem.num_error_mechanisms() > 0 - syndromes, data, logical = superdense_sample(3, - 2, - basis, - p_cx=0.0, - shots=30) - assert syndromes.shape == (30, 12) - assert not syndromes.any() - assert np.all(logical == expected) - - if __name__ == "__main__": pytest.main() From b7ed9a76161da0547bebb89075eb2ce018ae0f9d Mon Sep 17 00:00:00 2001 From: kvmto Date: Sat, 11 Jul 2026 12:39:18 +0200 Subject: [PATCH 8/8] Adopt the reference superdense schedule with declared inlined feedback The registered stabilizer_round now implements the reference superdense CX schedule (captured host-built layers) with the readout byproduct handled via the code-declared inlined-feedback matrices instead of an in-circuit correction. The framework-path DEM matches the reference construction mechanism-for-mechanism (golden tests, both bases, exact probabilities). Signed-off-by: kvmto --- .../cudaq_qec/plugins/codes/color_code.py | 580 +++- .../superdense_golden_d5_r5_allnoisy_X.dem | 2965 +++++++++++++++++ .../superdense_golden_d5_r5_allnoisy_Z.dem | 2964 ++++++++++++++++ libs/qec/python/tests/test_color_code.py | 527 ++- 4 files changed, 6989 insertions(+), 47 deletions(-) create mode 100644 libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_X.dem create mode 100644 libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_Z.dem diff --git a/libs/qec/python/cudaq_qec/plugins/codes/color_code.py b/libs/qec/python/cudaq_qec/plugins/codes/color_code.py index f5b9d8549..1f63e495e 100644 --- a/libs/qec/python/cudaq_qec/plugins/codes/color_code.py +++ b/libs/qec/python/cudaq_qec/plugins/codes/color_code.py @@ -592,6 +592,313 @@ def superdense_plaquette(self, plaq_idx: int) -> Dict[str, int]: return out + # ------------------------------------------------------------------ # + # Superdense paired-ancilla CX-layer schedule (host-side builders) + # ------------------------------------------------------------------ # + + def _rowmajor_cnot_layers(self) -> List[List[Tuple[int, int]]]: + """The 8 CNOT layers of the superdense schedule in the row-major + inverted-triangle numbering. + + The triangle is oriented with its widest row (d data qubits) on top, + narrowing to a single qubit at the bottom. + + Returns a length-8 list; each element is a list of (control, target) + pairs where data qubits are 0..num_data-1 (row-major, top-to-bottom) + and ancillas are num_data..num_data+2*num_plaquettes-1, grouped as + (a1, a2) = (num_data + 2p, num_data + 2p + 1) with a1 the X-ancilla + and a2 the Z-ancilla of plaquette p. + """ + d = int(self.distance) + num_data = (3 * d * d + 1) // 4 + num_plaquettes = (3 * (d * d - 1)) // 8 + num_rows_data_qubits = (3 * d - 1) // 2 + + layers: List[List[Tuple[int, int]]] = [] + + # tt=1..8 correspond to 8 layers + for tt in range(1, 9): + edges: List[Tuple[int, int]] = [] + + if tt == 1 or tt == 8: + # CNOT between the two ancilla qubits: control |+> (a1), + # target |0> (a2) + index = num_data + for _ in range(num_plaquettes): + a1 = index + a2 = index + 1 + edges.append((a1, a2)) + index += 2 + + elif tt == 2: + # First sequence (data = control) + data_qubit_index = d + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + elif tt == 3: + # Second sequence (data = control) + data_qubit_index = 0 + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + elif tt == 4: + # Third sequence (data = control) + data_qubit_index = 1 + index_ancilla = num_data + d - 1 + cols = d - 1 + for rr in range(num_rows_data_qubits - 2): + if rr % 3 == 0: + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + elif rr % 3 == 1: + for _ in range(cols): + edges.append((data_qubit_index, index_ancilla)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 2 + else: # rr % 3 == 2 + for cc in range(cols): + edges.append((data_qubit_index, index_ancilla)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + + elif tt == 5: + # First sequence (data = target) => ancilla is control + data_qubit_index = d + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + elif tt == 6: + # Second sequence (data = target) => ancilla is control + data_qubit_index = 0 + index_ancilla = num_data + cols = d - 1 + for rr in range(num_rows_data_qubits - 1): + if rr % 3 == 0: + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + cols -= 1 + elif rr % 3 == 1: + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + if cc == cols - 1: + index_ancilla += 3 + else: + index_ancilla += 1 + else: # rr % 3 == 2 + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 1 + + else: # tt == 7 + # Third sequence (data = target) => ancilla is control + data_qubit_index = 1 + index_ancilla = num_data + d - 1 + cols = d - 1 + for rr in range(num_rows_data_qubits - 2): + if rr % 3 == 0: + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + elif rr % 3 == 1: + for _ in range(cols): + edges.append((index_ancilla, data_qubit_index)) + data_qubit_index += 1 + index_ancilla += 1 + cols -= 2 + else: # rr % 3 == 2 + for cc in range(cols): + edges.append((index_ancilla, data_qubit_index)) + index_ancilla += 1 + if cc == cols - 1: + data_qubit_index += 3 + else: + data_qubit_index += 1 + + layers.append(sorted(edges)) + + return layers + + def _rowmajor_to_unified(self) -> Dict[int, int]: + """Bijection from the row-major inverted-triangle qubit numbering of + :meth:`_rowmajor_cnot_layers` to the unified label space (data + 0..N-1, X-ancilla N+i, Z-ancilla N+P+i for plaquette i). + + Data qubits: the grid's coordinates put row 0 at the top with rows + decreasing (more negative) downward, so sorting data ids by (row, col) + ascending enumerates them bottom-to-top, left-to-right -- exactly the + row-major order of the inverted triangle (widest row first). + + Ancillas: plaquettes are matched by their data-qubit support sets (the + data endpoints coupled to an ancilla pair across all layers), then + (a1, a2) = (num_data + 2p, num_data + 2p + 1) maps to + (N + i, N + P + i) for the matching plaquette index i. + """ + N = int(self.num_data) + P = int(self.num_plaquettes) + + ordered_data = sorted( + range(N), + key=lambda q: + (self.qubit_to_coord[q][0], self.qubit_to_coord[q][1])) + data_to_rowmajor = {q: i for i, q in enumerate(ordered_data)} + + layers = self._rowmajor_cnot_layers() + + # Support set (in row-major data ids) of each row-major plaquette. + support_to_plaq = {} + for p in range(P): + a1 = N + 2 * p + a2 = N + 2 * p + 1 + ds = set() + for layer in layers: + for c, t in layer: + if c < N and t in (a1, a2): + ds.add(c) + if c in (a1, a2) and t < N: + ds.add(t) + support_to_plaq[tuple(sorted(ds))] = p + + mapping = {i: q for q, i in data_to_rowmajor.items()} + for i, plaq in enumerate(self.plaquettes): + key = tuple(sorted( + data_to_rowmajor[q] for q in plaq['data_qubits'])) + p = support_to_plaq.get(key) + if p is None: + raise ValueError( + f"Plaquette {i} (data qubits {plaq['data_qubits']}) has no " + f"support-set match in the schedule") + mapping[N + 2 * p] = N + i + mapping[N + 2 * p + 1] = N + P + i + return mapping + + def _superdense_cnot_layers(self) -> List[List[Tuple[int, int]]]: + """The eight CNOT layers of the paired-ancilla superdense schedule in + the unified label space: data 0..N-1, X-ancilla N+i and Z-ancilla + N+P+i of plaquette i. Layers 0 and 7 entangle each plaquette's + ancilla pair; layers 1-3 couple data (control) into the pair; layers + 4-6 apply the mirrored ancilla-controlled CNOTs. + """ + mapping = self._rowmajor_to_unified() + return [ + sorted((mapping[c], mapping[t]) + for c, t in layer) + for layer in self._rowmajor_cnot_layers() + ] + + def z_side_data(self) -> List[List[int]]: + """Per plaquette (grid order), the data qubits coupled to its + Z-ancilla by the schedule; a conditional X on exactly these qubits is + the byproduct the Z-ancilla readout heralds.""" + layers = self._superdense_cnot_layers() + N, P = self.num_data, self.num_plaquettes + out = [set() for _ in range(P)] + for li in (1, 2, 3): + for c, t in layers[li]: + if t >= N + P: + out[t - N - P].add(c) + return [sorted(s) for s in out] + + def superdense_schedule(self) -> List[int]: + """Flattened one-round CX-layer schedule over the unified index space + (data 0..N-1, X-ancilla N..N+P-1, Z-ancilla N+P..N+2P-1). + + Encoding: the eight layers are concatenated as flat integers; within a + layer each (control, target) CNOT contributes the two ints control, + target, and every layer is closed by a -1 terminator. All qubit ids + are non-negative, so -1 unambiguously marks a layer boundary. A + consumer reads ints two at a time as (control, target) pairs and + advances to the next layer on -1. + """ + schedule: List[int] = [] + for layer in self._superdense_cnot_layers(): + for c, t in layer: + schedule.append(int(c)) + schedule.append(int(t)) + schedule.append(-1) + return schedule + # --------------------------------------------------------------------------- # CUDA-QX plugin glue: Pauli words over the data qubits @@ -625,15 +932,79 @@ def _plaquette_pauli_words( def _logical_pauli_words(grid: "ColorCodeGeometry") -> Tuple[str, str]: """Return (x_word, z_word) for the logical X/Z operators. - Both logicals use the bottom-edge representative (``logical_qubits``, - weight exactly d) — see ColorCodeGeometry._find_logical_qubits for why - the bottom edge is preferred over the full data-qubit support. + The logical X is the all-data-qubit representative (X on every one of the + N data qubits), matching the reference construction's all-data + ``logical_observable``. The logical Z is the bottom-edge representative + (``logical_qubits``, weight exactly d) — see + ColorCodeGeometry._find_logical_qubits for why the bottom edge is + preferred for Z (O(d) measurement error, no boundary detectors). + + The representatives are deliberately asymmetric. Both are valid: X on all + N data qubits commutes with every plaquette (all even weight, 4 or 6) and + anti-commutes with the bottom-edge logical Z (overlap = the d bottom-edge + qubits, d odd), so the pair is a logical X/Z. """ - chars = ['I'] * grid.num_data + x_word = 'X' * grid.num_data + z_chars = ['I'] * grid.num_data for q in grid.logical_qubits: - chars[q] = 'X' - x_word = ''.join(chars) - return x_word, x_word.replace('X', 'Z') + z_chars[q] = 'Z' + return x_word, ''.join(z_chars) + + +# --------------------------------------------------------------------------- +# Inlined-feedback declarations +# +# The registered stabilizer_round replays the reference superdense schedule +# with the byproduct left BARE: the mirrored ancilla-controlled CNOTs (layers +# 5-7) leave an uncorrected X byproduct on each plaquette's Z-ancilla-coupled +# data qubits (ColorCodeGeometry.z_side_data()), heralded by that Z-ancilla's +# readout record. The framework absorbs the byproduct downstream by XOR-ing the +# heralding records into the affected detectors / observables via these matrices +# (see libs/qec/lib/device/inlined_feedback.h), instead of a coherent in-round +# correction CX. +# --------------------------------------------------------------------------- + + +def _feedback_set(z_side_data: List[List[int]], support) -> List[int]: + """``F(S) = {a in [0,P) : |z_side_data[a] ∩ S| odd}``. + + ``z_side_data[a]`` is the data-qubit set coupled to plaquette ``a``'s + Z-ancilla by the schedule; its readout heralds a conditional X on exactly + those qubits. A record support ``S`` (a detector's or observable's + data-qubit support) picks up plaquette ``a``'s byproduct iff ``S`` overlaps + ``z_side_data[a]`` on an odd number of qubits. + """ + s = set(support) + return [ + a for a, zd in enumerate(z_side_data) + if len(s.intersection(zd)) % 2 == 1 + ] + + +def _assert_plaquette_order(plaquettes: List[dict]) -> None: + """Require min data-qubit index strictly increasing across grid-ordered + plaquettes; raise ValueError otherwise. + + ``to_parity_matrix`` (stabilizer_utils.cpp) sorts the Z-stabilizers by the + index of their first ``Z`` character, i.e. by min data-qubit index. The + memory circuit uses parity row k for the boundary detector of measurement + record k, and record k is plaquette k's Z-ancilla in this module's grid + order. Record k therefore maps to plaquette k only when the grid order is + already the min-data-qubit sort — i.e. min data-qubit is strictly + increasing across grid-ordered plaquettes (also guaranteeing the sort keys + are unique, so the non-stable std::sort cannot permute them). The declared + feedback matrices are indexed by that record order, so a violation would + silently misalign them. + """ + mins = [min(p['data_qubits']) for p in plaquettes] + for k in range(1, len(mins)): + if mins[k] <= mins[k - 1]: + raise ValueError( + "[color_code] plaquette order violates the min-data-qubit " + "strictly-increasing invariant required for measurement " + "record k to map to plaquette k (the framework sorts " + "stabilizers by min data-qubit index); min-data-qubit " + f"sequence={mins}.") # --------------------------------------------------------------------------- @@ -678,35 +1049,98 @@ def prepm(logicalQubit: patch): h(logicalQubit.data) -@cudaq.kernel -def stabilizer_round(logicalQubit: patch, x_stabilizers: list[int], - z_stabilizers: list[int]) -> list[cudaq.measure_handle]: - # x_stabilizers / z_stabilizers are the flattened - # [num_stabilizers x num_data] parity rows handed over by the framework - # (row i, column q at index i * num_data + q). - num_data = len(logicalQubit.data) - - # X-stabilizer half: ancilla in |+>, CX from ancilla onto plaquette data. - h(logicalQubit.ancx) - for xi in range(len(logicalQubit.ancx)): - for di in range(num_data): - if x_stabilizers[xi * num_data + di] == 1: - x.ctrl(logicalQubit.ancx[xi], logicalQubit.data[di]) - h(logicalQubit.ancx) - - # Z-stabilizer half: CX from plaquette data onto ancilla. - for zi in range(len(logicalQubit.ancz)): - for di in range(num_data): - if z_stabilizers[zi * num_data + di] == 1: - x.ctrl(logicalQubit.data[di], logicalQubit.ancz[zi]) - - # [Z][X] measurement order matches the framework's per-round detector - # layout. - results = mz([*logicalQubit.ancz, *logicalQubit.ancx]) - - reset(logicalQubit.ancx) - reset(logicalQubit.ancz) - return results +def _make_stabilizer_round(schedule_flat: list[int]): + """Build the per-round ``stabilizer_round`` kernel that replays the + reference superdense CX schedule exactly, as captured from + :meth:`ColorCodeGeometry.superdense_schedule`. + + The factory closes over the flat, ``-1``-terminated schedule so the kernel + walks a concrete gate list (a ``@cudaq.kernel`` defined inside a factory + captures a host ``list[int]``, and the capture survives the C++ + ``memory_circuit`` -> registered-Python-sub-kernel dispatch; each registered + instance keeps its own capture). + + Schedule encoding (unified index space, data ``0..N-1``, X-ancilla + ``N..N+P-1``, Z-ancilla ``N+P..N+2P-1``): ints are read two at a time as + ``(control, target)`` CNOT pairs; a ``-1`` closes the current layer. All + qubit ids are non-negative, so ``-1`` unambiguously marks a layer boundary. + Applying the pairs in flat order (skipping the ``-1`` markers) reproduces + the eight-layer gate sequence exactly: layers are emitted in order and each + layer's gates act on disjoint qubits, so the within-layer order is + immaterial. + + No byproduct-correction gates are emitted. The eight schedule layers include + the mirrored ancilla-controlled CNOTs (layers 5-7) that leave an uncorrected + X byproduct on the Z-ancilla-coupled data qubits; the correction is absorbed + downstream by the code's inlined-feedback declarations rather than by a + coherent in-round CX. + """ + + @cudaq.kernel + def _round(logicalQubit: patch, x_stabilizers: list[int], + z_stabilizers: list[int]) -> list[cudaq.measure_handle]: + # x_stabilizers / z_stabilizers arrive from the framework but are + # unused: the captured schedule alone drives the gate sequence. + num_data = len(logicalQubit.data) + P = len(logicalQubit.ancx) + + # X-ancilla (a1) prep in |+>. + h(logicalQubit.ancx) + + # Walk the captured schedule: (control, target) CNOT pairs, layers + # separated by -1. Index -> patch view: i < N -> data[i]; + # N <= i < N+P -> ancx[i-N]; N+P <= i < N+2P -> ancz[i-N-P]. + i = 0 + n = len(schedule_flat) + while i < n: + if schedule_flat[i] == -1: + i = i + 1 + else: + ci = schedule_flat[i] + ti = schedule_flat[i + 1] + if ci < num_data: + if ti < num_data: + x.ctrl(logicalQubit.data[ci], logicalQubit.data[ti]) + elif ti < num_data + P: + x.ctrl(logicalQubit.data[ci], + logicalQubit.ancx[ti - num_data]) + else: + x.ctrl(logicalQubit.data[ci], + logicalQubit.ancz[ti - num_data - P]) + elif ci < num_data + P: + if ti < num_data: + x.ctrl(logicalQubit.ancx[ci - num_data], + logicalQubit.data[ti]) + elif ti < num_data + P: + x.ctrl(logicalQubit.ancx[ci - num_data], + logicalQubit.ancx[ti - num_data]) + else: + x.ctrl(logicalQubit.ancx[ci - num_data], + logicalQubit.ancz[ti - num_data - P]) + else: + if ti < num_data: + x.ctrl(logicalQubit.ancz[ci - num_data - P], + logicalQubit.data[ti]) + elif ti < num_data + P: + x.ctrl(logicalQubit.ancz[ci - num_data - P], + logicalQubit.ancx[ti - num_data]) + else: + x.ctrl(logicalQubit.ancz[ci - num_data - P], + logicalQubit.ancz[ti - num_data - P]) + i = i + 2 + + # Rotate a1 back to the computational basis for the X readout. + h(logicalQubit.ancx) + + # [Z][X] record order (ancz first) — the order the framework detectors + # and the inlined-feedback matrices assume. + results = mz([*logicalQubit.ancz, *logicalQubit.ancx]) + + reset(logicalQubit.ancx) + reset(logicalQubit.ancz) + return results + + return _round # --------------------------------------------------------------------------- @@ -739,6 +1173,12 @@ def __init__(self, **kwargs): self.distance = kwargs['distance'] self.grid = ColorCodeGeometry(self.distance) + # The declared feedback matrices are indexed by the measurement-record + # order (record k = plaquette k's Z-ancilla in grid order). That only + # matches the framework's parity-row order when the grid order is the + # min-data-qubit sort; fail loudly otherwise. + _assert_plaquette_order(self.grid.plaquettes) + x_words, z_words = _plaquette_pauli_words(self.grid) self.stabilizers = [ cudaq.SpinOperator.from_word(w) for w in z_words + x_words @@ -749,11 +1189,20 @@ def __init__(self, **kwargs): ] self.operation_encodings = { - qec.operation.prep0: prep0, - qec.operation.prep1: prep1, - qec.operation.prepp: prepp, - qec.operation.prepm: prepm, - qec.operation.stabilizer_round: stabilizer_round, + qec.operation.prep0: + prep0, + qec.operation.prep1: + prep1, + qec.operation.prepp: + prepp, + qec.operation.prepm: + prepm, + # Per-instance round: replays this code's captured reference + # superdense schedule with the byproduct left uncorrected; the + # inlined-feedback getters declared below (get_inlined_feedback, + # get_observable_inlined_feedback_z) absorb it downstream. + qec.operation.stabilizer_round: + _make_stabilizer_round(self.grid.superdense_schedule()), } def get_num_data_qubits(self): @@ -774,6 +1223,55 @@ def get_num_x_stabilizers(self): def get_num_z_stabilizers(self): return self.grid.num_plaquettes + # ------------------------------------------------------------------ # + # Inlined-feedback declarations. Records are ordered [Z][X]: + # record k in [0,P) is plaquette k's Z-ancilla (a2); record P+k is + # plaquette k's X-ancilla (a1); numCols = 2P. Matrices are row-major + # uint8 (the bridge coerces dtype but requires a 2-D array). + # ------------------------------------------------------------------ # + + def get_inlined_feedback(self): + """[2P x 2P] detector feedback: fb[j][k] = 1 iff detector record j and + herald record k are both Z records (< P) and plaquette k is in + F(support of plaquette j). + + The bare schedule leaves an X byproduct on plaquette k's z_side_data, + heralded by Z-record k; it flips plaquette j's Z detector iff that + detector's support overlaps z_side_data[k] oddly (k in F(supp j)). X + records (>= P) neither carry nor receive the byproduct (an X byproduct + commutes with the X stabilizers), so those rows and columns are zero. + Diagonal entries (k in F(supp k)) are intentional: cudaq::detector + XOR-cancels the duplicated record. + """ + P = self.grid.num_plaquettes + z_side_data = self.grid.z_side_data() + fb = np.zeros((2 * P, 2 * P), dtype=np.uint8) + for j, plaq in enumerate(self.grid.plaquettes): + for k in _feedback_set(z_side_data, plaq['data_qubits']): + fb[j, k] = 1 + return fb + + def get_observable_inlined_feedback_z(self): + """[1 x 2P] logical-Z observable feedback: column k = 1 iff k is a Z + record (< P) and plaquette k is in F(logical_qubits). + + The logical Z (bottom edge, ``logical_qubits``) picks up plaquette k's + Z-ancilla-heralded X byproduct iff it overlaps z_side_data[k] oddly. + """ + P = self.grid.num_plaquettes + z_side_data = self.grid.z_side_data() + fb = np.zeros((1, 2 * P), dtype=np.uint8) + for k in _feedback_set(z_side_data, self.grid.logical_qubits): + fb[0, k] = 1 + return fb + + # get_observable_inlined_feedback_x is intentionally NOT defined: the + # X-basis logical (logical X read from data measured in X) commutes with + # the schedule's X byproduct, so it needs no feedback. The bridge maps the + # absent method to the base-class empty tensor, which flattens to no + # observable feedback on the X path (py_code.cpp get_observable_inlined_ + # feedback_x -> code::... empty; flatten_feedback_tensor empty -> {}). + if __name__ == "__main__": for d in [3, 5, 7]: diff --git a/libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_X.dem b/libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_X.dem new file mode 100644 index 000000000..229b3385d --- /dev/null +++ b/libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_X.dem @@ -0,0 +1,2965 @@ +# Reference superdense color-code DEM, d=5, 5 rounds, DEPOLARIZE2(0.01) +# per CX, ALL ROUNDS NOISY (physically stricter convention). +# Generator: reference superdense construction (superdense_memory kernel, +# cudaq.dem_from_kernel). The perfect-final-round originals are +# byte-reproduced by the same generator with its two noise guards restored +# (R > 1 and r < R - 1); here both are relaxed to p_cx > 0.0 so every +# stabilizer round is noisy. +error(0.001338700097173320998) D0 D1 D2 D18 D19 D20 L0 +error(0.0006697986788568588423) D0 D1 D2 D18 D19 L0 +error(0.0006697986788568588423) D0 D1 D2 D18 L0 +error(0.001338700097173320998) D0 D1 D2 D19 D20 L0 +error(0.0006697986788568588423) D0 D1 D2 D19 L0 +error(0.002673815958446297981) D0 D1 D2 D20 L0 +error(0.003340032800510209492) D0 D1 D2 L0 +error(0.002006705456917235505) D0 D1 D4 D10 +error(0.002006705456917235505) D0 D1 D4 D10 D19 +error(0.0006697986788568588423) D0 D1 D4 D10 D19 D20 +error(0.0006697986788568588423) D0 D1 D4 D10 D20 +error(0.001338700097173320998) D0 D1 D11 D18 D19 D20 L0 +error(0.0006697986788568588423) D0 D1 D11 D18 D19 L0 +error(0.0006697986788568588423) D0 D1 D11 D18 L0 +error(0.0006697986788568588423) D0 D1 D11 D19 D20 L0 +error(0.0006697986788568588423) D0 D1 D11 D20 L0 +error(0.001338700097173320998) D0 D1 D11 L0 +error(0.001338700097173320998) D0 D1 D18 D19 L0 +error(0.001338700097173320998) D0 D1 D18 L0 +error(0.002673815958446297981) D0 D1 D19 L0 +error(0.002673815958446297981) D0 D1 L0 +error(0.002006705456917235505) D0 D2 D9 +error(0.002006705456917235505) D0 D2 D9 D18 +error(0.0006697986788568588423) D0 D2 D9 D18 D19 +error(0.0006697986788568588423) D0 D2 D9 D19 +error(0.001338700097173320998) D0 D2 D18 D20 L0 +error(0.001338700097173320998) D0 D2 D18 L0 +error(0.002673815958446297981) D0 D2 D20 L0 +error(0.002673815958446297981) D0 D2 L0 +error(0.005333333333333313206) D0 D5 D11 D20 L0 +error(0.005333333333333313206) D0 D5 D11 L0 +error(0.007978628588222850399) D0 D9 +error(0.003340032800510209492) D0 D9 D18 +error(0.002006705456917235505) D0 D9 D18 D19 +error(0.001338700097173320998) D0 D9 D18 D19 D20 +error(0.001338700097173320998) D0 D9 D18 D20 +error(0.0006697986788568588423) D0 D9 D19 D20 +error(0.004669790293214320931) D0 D9 D20 +error(0.001338700097173320998) D0 D10 D11 D18 D19 D20 L0 +error(0.0006697986788568588423) D0 D10 D11 D18 D19 L0 +error(0.0006697986788568588423) D0 D10 D11 D18 L0 +error(0.0006697986788568588423) D0 D10 D11 D19 D20 L0 +error(0.0006697986788568588423) D0 D10 D11 D20 L0 +error(0.001338700097173320998) D0 D10 D11 L0 +error(0.002006705456917235505) D0 D10 D18 D19 L0 +error(0.0006697986788568588423) D0 D10 D18 L0 +error(0.0006697986788568588423) D0 D10 D19 L0 +error(0.002006705456917235505) D0 D10 L0 +error(0.001338700097173320998) D0 D11 D18 D20 L0 +error(0.001338700097173320998) D0 D11 D18 L0 +error(0.001338700097173320998) D0 D11 D20 L0 +error(0.001338700097173320998) D0 D11 L0 +error(0.002673815958446297981) D0 D18 L0 +error(0.002673815958446297981) D0 L0 +error(0.001338700097173320998) D1 D2 D4 D19 D20 D22 L0 +error(0.0006697986788568588423) D1 D2 D4 D19 D20 L0 +error(0.0006697986788568588423) D1 D2 D4 D19 L0 +error(0.001338700097173320998) D1 D2 D4 D20 D22 L0 +error(0.0006697986788568588423) D1 D2 D4 D20 L0 +error(0.002673815958446297981) D1 D2 D4 D22 L0 +error(0.003340032800510209492) D1 D2 D4 L0 +error(0.002006705456917235505) D1 D2 D5 D11 +error(0.002006705456917235505) D1 D2 D5 D11 D20 +error(0.0006697986788568588423) D1 D2 D5 D11 D20 D22 +error(0.0006697986788568588423) D1 D2 D5 D11 D22 +error(0.0006697986788568588423) D1 D2 D9 D18 D19 D20 L0 +error(0.0006697986788568588423) D1 D2 D9 D18 D19 L0 +error(0.001338700097173320998) D1 D2 D9 D18 L0 +error(0.0006697986788568588423) D1 D2 D9 D19 D20 L0 +error(0.0006697986788568588423) D1 D2 D9 D19 L0 +error(0.001338700097173320998) D1 D2 D9 L0 +error(0.0006697986788568588423) D1 D2 D13 D18 D19 L0 +error(0.0006697986788568588423) D1 D2 D13 D18 D20 D22 L0 +error(0.001338700097173320998) D1 D2 D13 D19 D20 D22 L0 +error(0.0006697986788568588423) D1 D2 D13 D19 D20 L0 +error(0.0006697986788568588423) D1 D2 D13 D22 L0 +error(0.001338700097173320998) D1 D2 D13 L0 +error(0.001338700097173320998) D1 D4 D19 D22 L0 +error(0.001338700097173320998) D1 D4 D19 L0 +error(0.002673815958446297981) D1 D4 D22 L0 +error(0.002673815958446297981) D1 D4 L0 +error(0.005333333333333313206) D1 D8 D13 D22 L0 +error(0.005333333333333313206) D1 D8 D13 L0 +error(0.006657753962803452177) D1 D10 +error(0.001338700097173320998) D1 D10 D18 +error(0.0006697986788568588423) D1 D10 D18 D19 +error(0.0006697986788568588423) D1 D10 D18 D19 D20 +error(0.002673815958446297981) D1 D10 D19 +error(0.001338700097173320998) D1 D10 D19 D20 +error(0.001338700097173320998) D1 D10 D19 D20 D22 +error(0.001338700097173320998) D1 D10 D19 D22 +error(0.0006697986788568588423) D1 D10 D20 D22 +error(0.004669790293214320931) D1 D10 D22 +error(0.0006697986788568588423) D1 D11 D13 D18 D19 L0 +error(0.0006697986788568588423) D1 D11 D13 D18 D20 D22 L0 +error(0.001338700097173320998) D1 D11 D13 D19 D20 D22 L0 +error(0.0006697986788568588423) D1 D11 D13 D19 D20 L0 +error(0.0006697986788568588423) D1 D11 D13 D22 L0 +error(0.001338700097173320998) D1 D11 D13 L0 +error(0.001338700097173320998) D1 D13 D19 D22 L0 +error(0.001338700097173320998) D1 D13 D19 L0 +error(0.001338700097173320998) D1 D13 D22 L0 +error(0.001338700097173320998) D1 D13 L0 +error(0.001338700097173320998) D2 D3 D5 D20 D21 D23 L0 +error(0.0006697986788568588423) D2 D3 D5 D20 D21 L0 +error(0.0006697986788568588423) D2 D3 D5 D20 L0 +error(0.001338700097173320998) D2 D3 D5 D21 D23 L0 +error(0.0006697986788568588423) D2 D3 D5 D21 L0 +error(0.002673815958446297981) D2 D3 D5 D23 L0 +error(0.003340032800510209492) D2 D3 D5 L0 +error(0.002006705456917235505) D2 D3 D7 D12 +error(0.002006705456917235505) D2 D3 D7 D12 D21 +error(0.0006697986788568588423) D2 D3 D7 D12 D21 D23 +error(0.0006697986788568588423) D2 D3 D7 D12 D23 +error(0.001338700097173320998) D2 D3 D14 D20 D21 D23 L0 +error(0.0006697986788568588423) D2 D3 D14 D20 D21 L0 +error(0.0006697986788568588423) D2 D3 D14 D20 L0 +error(0.0006697986788568588423) D2 D3 D14 D21 D23 L0 +error(0.0006697986788568588423) D2 D3 D14 D23 L0 +error(0.001338700097173320998) D2 D3 D14 L0 +error(0.001338700097173320998) D2 D3 D20 D21 L0 +error(0.001338700097173320998) D2 D3 D20 L0 +error(0.002673815958446297981) D2 D3 D21 L0 +error(0.002673815958446297981) D2 D3 L0 +error(0.001338700097173320998) D2 D4 D5 D20 D22 D23 L0 +error(0.0006697986788568588423) D2 D4 D5 D20 D22 L0 +error(0.0006697986788568588423) D2 D4 D5 D20 L0 +error(0.001338700097173320998) D2 D4 D5 D22 D23 L0 +error(0.0006697986788568588423) D2 D4 D5 D22 L0 +error(0.002673815958446297981) D2 D4 D5 D23 L0 +error(0.003340032800510209492) D2 D4 D5 L0 +error(0.002006705456917235505) D2 D4 D8 D13 +error(0.002006705456917235505) D2 D4 D8 D13 D22 +error(0.0006697986788568588423) D2 D4 D8 D13 D22 D23 +error(0.0006697986788568588423) D2 D4 D8 D13 D23 +error(0.0006697986788568588423) D2 D4 D10 D19 D20 D22 L0 +error(0.0006697986788568588423) D2 D4 D10 D19 D20 L0 +error(0.001338700097173320998) D2 D4 D10 D19 L0 +error(0.0006697986788568588423) D2 D4 D10 D20 D22 L0 +error(0.0006697986788568588423) D2 D4 D10 D20 L0 +error(0.001338700097173320998) D2 D4 D10 L0 +error(0.0006697986788568588423) D2 D4 D14 D19 D20 L0 +error(0.0006697986788568588423) D2 D4 D14 D19 D22 D23 L0 +error(0.001338700097173320998) D2 D4 D14 D20 D22 D23 L0 +error(0.0006697986788568588423) D2 D4 D14 D20 D22 L0 +error(0.0006697986788568588423) D2 D4 D14 D23 L0 +error(0.001338700097173320998) D2 D4 D14 L0 +error(0.002006705456917235505) D2 D5 D11 +error(0.002006705456917235505) D2 D5 D11 D20 +error(0.0006697986788568588423) D2 D5 D11 D20 D21 +error(0.0006697986788568588423) D2 D5 D11 D21 +error(0.0006697986788568588423) D2 D9 D18 D20 L0 +error(0.004669790293214320931) D2 D9 D18 L0 +error(0.0006697986788568588423) D2 D9 D20 L0 +error(0.004669790293214320931) D2 D9 L0 +error(0.007978628588222850399) D2 D11 +error(0.001338700097173320998) D2 D11 D18 +error(0.001338700097173320998) D2 D11 D18 D19 +error(0.0006697986788568588423) D2 D11 D18 D19 D20 +error(0.0006697986788568588423) D2 D11 D18 D20 +error(0.001338700097173320998) D2 D11 D18 D20 D21 +error(0.001338700097173320998) D2 D11 D18 D20 D22 +error(0.004005357180252827609) D2 D11 D18 D23 +error(0.0006697986788568588423) D2 D11 D19 D20 D22 +error(0.002673815958446297981) D2 D11 D20 +error(0.0006697986788568588423) D2 D11 D20 D21 +error(0.001338700097173320998) D2 D11 D20 D21 D23 +error(0.001338700097173320998) D2 D11 D20 D22 D23 +error(0.0006697986788568588423) D2 D11 D21 D23 +error(0.0006697986788568588423) D2 D11 D22 D23 +error(0.0006697986788568588423) D2 D12 D14 D18 D20 D21 L0 +error(0.0006697986788568588423) D2 D12 D14 D18 D23 L0 +error(0.001338700097173320998) D2 D12 D14 D20 D21 D23 L0 +error(0.0006697986788568588423) D2 D12 D14 D20 L0 +error(0.0006697986788568588423) D2 D12 D14 D21 D23 L0 +error(0.001338700097173320998) D2 D12 D14 L0 +error(0.0006697986788568588423) D2 D12 D18 D20 D21 L0 +error(0.0006697986788568588423) D2 D12 D18 L0 +error(0.001338700097173320998) D2 D12 D20 D21 L0 +error(0.0006697986788568588423) D2 D12 D20 L0 +error(0.0006697986788568588423) D2 D12 D21 L0 +error(0.001338700097173320998) D2 D12 L0 +error(0.0006697986788568588423) D2 D13 D14 D18 D20 D22 L0 +error(0.0006697986788568588423) D2 D13 D14 D18 D23 L0 +error(0.0006697986788568588423) D2 D13 D14 D19 D20 L0 +error(0.0006697986788568588423) D2 D13 D14 D19 D22 D23 L0 +error(0.001338700097173320998) D2 D13 D14 D20 D22 D23 L0 +error(0.001338700097173320998) D2 D13 D14 L0 +error(0.005333333333333313206) D2 D14 D23 L0 +error(0.005333333333333313206) D2 D14 L0 +error(0.001338700097173320998) D3 D5 D7 D21 D23 D25 L0 +error(0.0006697986788568588423) D3 D5 D7 D21 D23 L0 +error(0.0006697986788568588423) D3 D5 D7 D21 L0 +error(0.001338700097173320998) D3 D5 D7 D23 D25 L0 +error(0.0006697986788568588423) D3 D5 D7 D23 L0 +error(0.002673815958446297981) D3 D5 D7 D25 L0 +error(0.003340032800510209492) D3 D5 D7 L0 +error(0.0006697986788568588423) D3 D5 D11 D20 D21 D23 L0 +error(0.0006697986788568588423) D3 D5 D11 D20 D21 L0 +error(0.001338700097173320998) D3 D5 D11 D20 L0 +error(0.0006697986788568588423) D3 D5 D11 D21 D23 L0 +error(0.0006697986788568588423) D3 D5 D11 D21 L0 +error(0.001338700097173320998) D3 D5 D11 L0 +error(0.002006705456917235505) D3 D5 D14 +error(0.002006705456917235505) D3 D5 D14 D23 +error(0.0006697986788568588423) D3 D5 D14 D23 D25 +error(0.0006697986788568588423) D3 D5 D14 D25 +error(0.0006697986788568588423) D3 D5 D16 D20 D21 L0 +error(0.0006697986788568588423) D3 D5 D16 D20 D23 D25 L0 +error(0.001338700097173320998) D3 D5 D16 D21 D23 D25 L0 +error(0.0006697986788568588423) D3 D5 D16 D21 D23 L0 +error(0.0006697986788568588423) D3 D5 D16 D25 L0 +error(0.001338700097173320998) D3 D5 D16 L0 +error(0.005333333333333313206) D3 D7 D16 +error(0.005333333333333313206) D3 D7 D16 D25 +error(0.001338700097173320998) D3 D7 D21 D25 L0 +error(0.001338700097173320998) D3 D7 D21 L0 +error(0.002673815958446297981) D3 D7 D25 L0 +error(0.002673815958446297981) D3 D7 L0 +error(0.006657753962803452177) D3 D12 +error(0.001338700097173320998) D3 D12 D20 +error(0.0006697986788568588423) D3 D12 D20 D21 +error(0.0006697986788568588423) D3 D12 D20 D21 D23 +error(0.002673815958446297981) D3 D12 D21 +error(0.001338700097173320998) D3 D12 D21 D23 +error(0.001338700097173320998) D3 D12 D21 D23 D25 +error(0.001338700097173320998) D3 D12 D21 D25 +error(0.0006697986788568588423) D3 D12 D23 D25 +error(0.004669790293214320931) D3 D12 D25 +error(0.0006697986788568588423) D3 D14 D16 D20 D21 L0 +error(0.0006697986788568588423) D3 D14 D16 D20 D23 D25 L0 +error(0.001338700097173320998) D3 D14 D16 D21 D23 D25 L0 +error(0.0006697986788568588423) D3 D14 D16 D21 D23 L0 +error(0.0006697986788568588423) D3 D14 D16 D25 L0 +error(0.001338700097173320998) D3 D14 D16 L0 +error(0.001338700097173320998) D3 D16 D21 D25 L0 +error(0.001338700097173320998) D3 D16 D21 L0 +error(0.001338700097173320998) D3 D16 D25 L0 +error(0.001338700097173320998) D3 D16 L0 +error(0.001338700097173320998) D4 D5 D8 D22 D23 D26 L0 +error(0.0006697986788568588423) D4 D5 D8 D22 D23 L0 +error(0.0006697986788568588423) D4 D5 D8 D22 L0 +error(0.001338700097173320998) D4 D5 D8 D23 D26 L0 +error(0.0006697986788568588423) D4 D5 D8 D23 L0 +error(0.002673815958446297981) D4 D5 D8 D26 L0 +error(0.003340032800510209492) D4 D5 D8 L0 +error(0.0006697986788568588423) D4 D5 D11 D20 D22 D23 L0 +error(0.0006697986788568588423) D4 D5 D11 D20 D22 L0 +error(0.001338700097173320998) D4 D5 D11 D20 L0 +error(0.0006697986788568588423) D4 D5 D11 D22 D23 L0 +error(0.0006697986788568588423) D4 D5 D11 D22 L0 +error(0.001338700097173320998) D4 D5 D11 L0 +error(0.002006705456917235505) D4 D5 D14 +error(0.002006705456917235505) D4 D5 D14 D23 +error(0.0006697986788568588423) D4 D5 D14 D23 D26 +error(0.0006697986788568588423) D4 D5 D14 D26 +error(0.0006697986788568588423) D4 D5 D17 D20 D22 L0 +error(0.0006697986788568588423) D4 D5 D17 D20 D23 D26 L0 +error(0.001338700097173320998) D4 D5 D17 D22 D23 D26 L0 +error(0.0006697986788568588423) D4 D5 D17 D22 D23 L0 +error(0.0006697986788568588423) D4 D5 D17 D26 L0 +error(0.001338700097173320998) D4 D5 D17 L0 +error(0.001338700097173320998) D4 D6 D8 D22 D24 D26 L0 +error(0.0006697986788568588423) D4 D6 D8 D22 D24 L0 +error(0.0006697986788568588423) D4 D6 D8 D22 L0 +error(0.001338700097173320998) D4 D6 D8 D24 D26 L0 +error(0.0006697986788568588423) D4 D6 D8 D24 L0 +error(0.002673815958446297981) D4 D6 D8 D26 L0 +error(0.003340032800510209492) D4 D6 D8 L0 +error(0.002006705456917235505) D4 D6 D15 +error(0.002006705456917235505) D4 D6 D15 D24 +error(0.0006697986788568588423) D4 D6 D15 D24 D26 +error(0.0006697986788568588423) D4 D6 D15 D26 +error(0.001338700097173320998) D4 D6 D17 D22 D24 D26 L0 +error(0.0006697986788568588423) D4 D6 D17 D22 D24 L0 +error(0.0006697986788568588423) D4 D6 D17 D22 L0 +error(0.0006697986788568588423) D4 D6 D17 D24 D26 L0 +error(0.0006697986788568588423) D4 D6 D17 D26 L0 +error(0.001338700097173320998) D4 D6 D17 L0 +error(0.001338700097173320998) D4 D6 D22 D24 L0 +error(0.001338700097173320998) D4 D6 D22 L0 +error(0.002673815958446297981) D4 D6 D24 L0 +error(0.002673815958446297981) D4 D6 L0 +error(0.002006705456917235505) D4 D8 D13 +error(0.002006705456917235505) D4 D8 D13 D22 +error(0.0006697986788568588423) D4 D8 D13 D22 D24 +error(0.0006697986788568588423) D4 D8 D13 D24 +error(0.005333333333333313206) D4 D8 D17 +error(0.005333333333333313206) D4 D8 D17 D26 +error(0.0006697986788568588423) D4 D10 D19 D22 L0 +error(0.004669790293214320931) D4 D10 D19 L0 +error(0.0006697986788568588423) D4 D10 D22 L0 +error(0.004669790293214320931) D4 D10 L0 +error(0.007978628588222850399) D4 D13 +error(0.001338700097173320998) D4 D13 D19 +error(0.001338700097173320998) D4 D13 D19 D20 +error(0.0006697986788568588423) D4 D13 D19 D20 D22 +error(0.0006697986788568588423) D4 D13 D19 D22 +error(0.001338700097173320998) D4 D13 D19 D22 D23 +error(0.001338700097173320998) D4 D13 D19 D22 D24 +error(0.004005357180252827609) D4 D13 D19 D26 +error(0.0006697986788568588423) D4 D13 D20 D22 D23 +error(0.002673815958446297981) D4 D13 D22 +error(0.001338700097173320998) D4 D13 D22 D23 D26 +error(0.0006697986788568588423) D4 D13 D22 D24 +error(0.001338700097173320998) D4 D13 D22 D24 D26 +error(0.0006697986788568588423) D4 D13 D23 D26 +error(0.0006697986788568588423) D4 D13 D24 D26 +error(0.0006697986788568588423) D4 D14 D17 D19 D22 D23 L0 +error(0.0006697986788568588423) D4 D14 D17 D19 D26 L0 +error(0.0006697986788568588423) D4 D14 D17 D20 D22 L0 +error(0.0006697986788568588423) D4 D14 D17 D20 D23 D26 L0 +error(0.001338700097173320998) D4 D14 D17 D22 D23 D26 L0 +error(0.001338700097173320998) D4 D14 D17 L0 +error(0.0006697986788568588423) D4 D15 D17 D19 D22 D24 L0 +error(0.0006697986788568588423) D4 D15 D17 D19 D26 L0 +error(0.001338700097173320998) D4 D15 D17 D22 D24 D26 L0 +error(0.0006697986788568588423) D4 D15 D17 D22 L0 +error(0.0006697986788568588423) D4 D15 D17 D24 D26 L0 +error(0.001338700097173320998) D4 D15 D17 L0 +error(0.0006697986788568588423) D4 D15 D19 D22 D24 L0 +error(0.0006697986788568588423) D4 D15 D19 L0 +error(0.001338700097173320998) D4 D15 D22 D24 L0 +error(0.0006697986788568588423) D4 D15 D22 L0 +error(0.0006697986788568588423) D4 D15 D24 L0 +error(0.001338700097173320998) D4 D15 L0 +error(0.0006697986788568588423) D5 D7 D12 D21 D23 D25 L0 +error(0.0006697986788568588423) D5 D7 D12 D21 D23 L0 +error(0.001338700097173320998) D5 D7 D12 D21 L0 +error(0.0006697986788568588423) D5 D7 D12 D23 D25 L0 +error(0.0006697986788568588423) D5 D7 D12 D23 L0 +error(0.001338700097173320998) D5 D7 D12 L0 +error(0.0006697986788568588423) D5 D7 D21 D23 L0 +error(0.0006697986788568588423) D5 D7 D21 D25 L0 +error(0.001338700097173320998) D5 D7 D23 D25 L0 +error(0.0006697986788568588423) D5 D7 D23 L0 +error(0.002006705456917235505) D5 D7 D25 L0 +error(0.002673815958446297981) D5 D7 L0 +error(0.0006697986788568588423) D5 D8 D13 D22 D23 D26 L0 +error(0.0006697986788568588423) D5 D8 D13 D22 D23 L0 +error(0.001338700097173320998) D5 D8 D13 D22 L0 +error(0.0006697986788568588423) D5 D8 D13 D23 D26 L0 +error(0.0006697986788568588423) D5 D8 D13 D23 L0 +error(0.001338700097173320998) D5 D8 D13 L0 +error(0.0006697986788568588423) D5 D8 D22 D23 L0 +error(0.0006697986788568588423) D5 D8 D22 D26 L0 +error(0.001338700097173320998) D5 D8 D23 D26 L0 +error(0.0006697986788568588423) D5 D8 D23 L0 +error(0.002006705456917235505) D5 D8 D26 L0 +error(0.002673815958446297981) D5 D8 L0 +error(0.007978628588222850399) D5 D14 +error(0.004005357180252827609) D5 D14 D20 +error(0.001338700097173320998) D5 D14 D20 D21 +error(0.0006697986788568588423) D5 D14 D20 D21 D23 +error(0.001338700097173320998) D5 D14 D20 D22 +error(0.0006697986788568588423) D5 D14 D20 D22 D23 +error(0.001338700097173320998) D5 D14 D20 D23 D25 +error(0.001338700097173320998) D5 D14 D20 D23 D26 +error(0.0006697986788568588423) D5 D14 D21 D23 D25 +error(0.0006697986788568588423) D5 D14 D22 D23 D26 +error(0.002673815958446297981) D5 D14 D23 +error(0.001338700097173320998) D5 D14 D23 D25 +error(0.001338700097173320998) D5 D14 D23 D26 +error(0.0006697986788568588423) D5 D14 D25 +error(0.0006697986788568588423) D5 D14 D26 +error(0.0006697986788568588423) D5 D16 D20 D23 D25 L0 +error(0.0006697986788568588423) D5 D16 D20 L0 +error(0.0006697986788568588423) D5 D16 D21 D23 L0 +error(0.0006697986788568588423) D5 D16 D21 D25 L0 +error(0.001338700097173320998) D5 D16 D23 D25 L0 +error(0.002673815958446297981) D5 D16 D25 L0 +error(0.004005357180252827609) D5 D16 L0 +error(0.0006697986788568588423) D5 D17 D20 D23 D26 L0 +error(0.0006697986788568588423) D5 D17 D20 L0 +error(0.0006697986788568588423) D5 D17 D22 D23 L0 +error(0.0006697986788568588423) D5 D17 D22 D26 L0 +error(0.001338700097173320998) D5 D17 D23 D26 L0 +error(0.002673815958446297981) D5 D17 D26 L0 +error(0.004005357180252827609) D5 D17 L0 +error(0.0006697986788568588423) D6 D8 D13 D22 D24 D26 L0 +error(0.0006697986788568588423) D6 D8 D13 D22 D24 L0 +error(0.001338700097173320998) D6 D8 D13 D22 L0 +error(0.0006697986788568588423) D6 D8 D13 D24 D26 L0 +error(0.0006697986788568588423) D6 D8 D13 D24 L0 +error(0.001338700097173320998) D6 D8 D13 L0 +error(0.0006697986788568588423) D6 D8 D22 D24 L0 +error(0.0006697986788568588423) D6 D8 D22 D26 L0 +error(0.001338700097173320998) D6 D8 D24 D26 L0 +error(0.0006697986788568588423) D6 D8 D24 L0 +error(0.002006705456917235505) D6 D8 D26 L0 +error(0.002673815958446297981) D6 D8 L0 +error(0.01126536362635755656) D6 D15 +error(0.001338700097173320998) D6 D15 D22 +error(0.0006697986788568588423) D6 D15 D22 D24 +error(0.0006697986788568588423) D6 D15 D22 D24 D26 +error(0.004005357180252827609) D6 D15 D24 +error(0.002673815958446297981) D6 D15 D24 D26 +error(0.0006697986788568588423) D6 D15 D26 +error(0.0006697986788568588423) D6 D17 D22 D24 L0 +error(0.0006697986788568588423) D6 D17 D22 D26 L0 +error(0.002006705456917235505) D6 D17 D24 D26 L0 +error(0.002673815958446297981) D6 D17 D26 L0 +error(0.004669790293214320931) D6 D17 L0 +error(0.002673815958446297981) D6 D24 L0 +error(0.002673815958446297981) D6 L0 +error(0.0006697986788568588423) D7 D12 D21 D25 L0 +error(0.004669790293214320931) D7 D12 D21 L0 +error(0.0006697986788568588423) D7 D12 D25 L0 +error(0.004669790293214320931) D7 D12 L0 +error(0.001338700097173320998) D7 D14 D23 D25 L0 +error(0.001338700097173320998) D7 D14 D23 L0 +error(0.001338700097173320998) D7 D14 D25 L0 +error(0.001338700097173320998) D7 D14 L0 +error(0.007978628588222850399) D7 D16 +error(0.001338700097173320998) D7 D16 D21 +error(0.001338700097173320998) D7 D16 D21 D23 +error(0.0006697986788568588423) D7 D16 D21 D23 D25 +error(0.004669790293214320931) D7 D16 D21 D25 +error(0.0006697986788568588423) D7 D16 D23 D25 +error(0.004669790293214320931) D7 D16 D25 +error(0.0006697986788568588423) D7 D21 D25 L0 +error(0.0006697986788568588423) D7 D21 L0 +error(0.002006705456917235505) D7 D25 L0 +error(0.002006705456917235505) D7 L0 +error(0.001338700097173320998) D8 D14 D23 D26 L0 +error(0.001338700097173320998) D8 D14 D23 L0 +error(0.001338700097173320998) D8 D14 D26 L0 +error(0.001338700097173320998) D8 D14 L0 +error(0.001338700097173320998) D8 D15 D24 D26 L0 +error(0.001338700097173320998) D8 D15 D24 L0 +error(0.001338700097173320998) D8 D15 D26 L0 +error(0.001338700097173320998) D8 D15 L0 +error(0.007978628588222850399) D8 D17 +error(0.001338700097173320998) D8 D17 D22 D23 +error(0.0006697986788568588423) D8 D17 D22 D23 D26 +error(0.001338700097173320998) D8 D17 D22 D24 +error(0.0006697986788568588423) D8 D17 D22 D24 D26 +error(0.004005357180252827609) D8 D17 D22 D26 +error(0.0006697986788568588423) D8 D17 D23 D26 +error(0.0006697986788568588423) D8 D17 D24 D26 +error(0.004005357180252827609) D8 D17 D26 +error(0.001338700097173320998) D9 D10 D11 D18 D19 D20 L0 +error(0.001338700097173320998) D9 D10 D11 D18 D19 D38 L0 +error(0.0006697986788568588423) D9 D10 D11 D18 D19 L0 +error(0.0006697986788568588423) D9 D10 D11 D18 D36 L0 +error(0.001338700097173320998) D9 D10 D11 D18 D37 D38 L0 +error(0.0006697986788568588423) D9 D10 D11 D19 D37 L0 +error(0.0006697986788568588423) D9 D10 D11 D20 D36 D37 L0 +error(0.001338700097173320998) D9 D10 D11 D20 D38 L0 +error(0.0006697986788568588423) D9 D10 D11 D20 L0 +error(0.001338700097173320998) D9 D10 D11 D36 D37 D38 L0 +error(0.003340032800510209492) D9 D10 D11 L0 +error(0.0006697986788568588423) D9 D10 D13 D18 D19 D28 +error(0.0006697986788568588423) D9 D10 D13 D18 D19 D28 D38 +error(0.0006697986788568588423) D9 D10 D13 D18 D28 D37 +error(0.0006697986788568588423) D9 D10 D13 D18 D28 D37 D38 +error(0.001338700097173320998) D9 D10 D13 D19 D28 D37 +error(0.001338700097173320998) D9 D10 D13 D28 +error(0.002006705456917235505) D9 D10 D18 D19 L0 +error(0.0006697986788568588423) D9 D10 D18 D36 L0 +error(0.001338700097173320998) D9 D10 D18 D37 L0 +error(0.0006697986788568588423) D9 D10 D19 D29 D36 L0 +error(0.0006697986788568588423) D9 D10 D19 D29 D37 D38 L0 +error(0.0006697986788568588423) D9 D10 D19 D36 L0 +error(0.001338700097173320998) D9 D10 D19 D37 L0 +error(0.0006697986788568588423) D9 D10 D20 D29 D36 D37 L0 +error(0.0006697986788568588423) D9 D10 D20 D29 D38 L0 +error(0.001338700097173320998) D9 D10 D29 D36 D37 D38 L0 +error(0.001338700097173320998) D9 D10 D29 L0 +error(0.001338700097173320998) D9 D10 D36 D37 L0 +error(0.003340032800510209492) D9 D10 L0 +error(0.001338700097173320998) D9 D11 D18 D20 L0 +error(0.0006697986788568588423) D9 D11 D18 D27 +error(0.001338700097173320998) D9 D11 D18 D27 D36 +error(0.0006697986788568588423) D9 D11 D18 D27 D37 +error(0.0006697986788568588423) D9 D11 D18 D36 L0 +error(0.001338700097173320998) D9 D11 D18 D38 L0 +error(0.0006697986788568588423) D9 D11 D18 L0 +error(0.0006697986788568588423) D9 D11 D20 D36 L0 +error(0.001338700097173320998) D9 D11 D20 D38 L0 +error(0.0006697986788568588423) D9 D11 D20 L0 +error(0.001338700097173320998) D9 D11 D27 +error(0.0006697986788568588423) D9 D11 D27 D36 +error(0.0006697986788568588423) D9 D11 D27 D36 D37 +error(0.001338700097173320998) D9 D11 D36 D38 L0 +error(0.002673815958446297981) D9 D11 L0 +error(0.0006697986788568588423) D9 D14 D18 D19 D20 D29 L0 +error(0.0006697986788568588423) D9 D14 D18 D19 D29 D38 L0 +error(0.0006697986788568588423) D9 D14 D18 D20 D29 L0 +error(0.0006697986788568588423) D9 D14 D18 D29 D38 L0 +error(0.004005357180252827609) D9 D14 D20 D29 D38 L0 +error(0.004005357180252827609) D9 D14 D29 L0 +error(0.001338700097173320998) D9 D18 D27 +error(0.002673815958446297981) D9 D18 D27 D36 +error(0.001338700097173320998) D9 D18 D27 D36 D37 +error(0.0006697986788568588423) D9 D18 D27 D37 D38 +error(0.004669790293214320931) D9 D18 D27 D38 +error(0.0006697986788568588423) D9 D18 D28 D29 D36 D37 L0 +error(0.0006697986788568588423) D9 D18 D28 D29 D38 L0 +error(0.0006697986788568588423) D9 D18 D28 D36 D37 L0 +error(0.0006697986788568588423) D9 D18 D28 L0 +error(0.0006697986788568588423) D9 D18 D29 D36 L0 +error(0.0006697986788568588423) D9 D18 D29 D38 L0 +error(0.001338700097173320998) D9 D18 D36 L0 +error(0.002673815958446297981) D9 D18 L0 +error(0.0006697986788568588423) D9 D19 D28 D29 D36 L0 +error(0.0006697986788568588423) D9 D19 D28 D29 D37 D38 L0 +error(0.0006697986788568588423) D9 D19 D28 D36 L0 +error(0.0006697986788568588423) D9 D19 D28 D37 L0 +error(0.0006697986788568588423) D9 D20 D29 D36 L0 +error(0.0006697986788568588423) D9 D20 D29 D38 L0 +error(0.006657753962803452177) D9 D27 +error(0.0006697986788568588423) D9 D27 D36 +error(0.0006697986788568588423) D9 D27 D36 D37 +error(0.001338700097173320998) D9 D27 D36 D37 D38 +error(0.001338700097173320998) D9 D27 D36 D38 +error(0.001338700097173320998) D9 D28 D29 D36 D37 D38 L0 +error(0.001338700097173320998) D9 D28 D29 L0 +error(0.001338700097173320998) D9 D28 D36 D37 L0 +error(0.001338700097173320998) D9 D28 L0 +error(0.001338700097173320998) D9 D29 D36 D38 L0 +error(0.001338700097173320998) D9 D29 L0 +error(0.001338700097173320998) D9 D36 L0 +error(0.002673815958446297981) D9 L0 +error(0.001338700097173320998) D10 D11 D13 D19 D20 D22 L0 +error(0.001338700097173320998) D10 D11 D13 D19 D20 D40 L0 +error(0.0006697986788568588423) D10 D11 D13 D19 D20 L0 +error(0.0006697986788568588423) D10 D11 D13 D19 D37 L0 +error(0.001338700097173320998) D10 D11 D13 D19 D38 D40 L0 +error(0.0006697986788568588423) D10 D11 D13 D20 D38 L0 +error(0.0006697986788568588423) D10 D11 D13 D22 D37 D38 L0 +error(0.001338700097173320998) D10 D11 D13 D22 D40 L0 +error(0.0006697986788568588423) D10 D11 D13 D22 L0 +error(0.001338700097173320998) D10 D11 D13 D37 D38 D40 L0 +error(0.003340032800510209492) D10 D11 D13 L0 +error(0.0006697986788568588423) D10 D11 D14 D18 D19 D20 D29 +error(0.0006697986788568588423) D10 D11 D14 D18 D19 D29 D38 +error(0.0006697986788568588423) D10 D11 D14 D19 D20 D29 D40 +error(0.0006697986788568588423) D10 D11 D14 D19 D29 D38 D40 +error(0.001338700097173320998) D10 D11 D14 D20 D29 D38 +error(0.001338700097173320998) D10 D11 D14 D29 +error(0.001338700097173320998) D10 D11 D18 D27 D36 L0 +error(0.0006697986788568588423) D10 D11 D18 D27 D37 D38 L0 +error(0.0006697986788568588423) D10 D11 D18 D27 D37 L0 +error(0.0006697986788568588423) D10 D11 D20 D31 D36 D37 L0 +error(0.0006697986788568588423) D10 D11 D20 D31 D36 D38 D40 L0 +error(0.0006697986788568588423) D10 D11 D22 D31 D37 D38 L0 +error(0.0006697986788568588423) D10 D11 D22 D31 D40 L0 +error(0.0006697986788568588423) D10 D11 D27 D36 D37 D38 L0 +error(0.0006697986788568588423) D10 D11 D27 D36 D37 L0 +error(0.001338700097173320998) D10 D11 D27 L0 +error(0.001338700097173320998) D10 D11 D31 D37 D38 D40 L0 +error(0.001338700097173320998) D10 D11 D31 L0 +error(0.001338700097173320998) D10 D13 D19 D22 L0 +error(0.0006697986788568588423) D10 D13 D19 D37 L0 +error(0.001338700097173320998) D10 D13 D19 D40 L0 +error(0.0006697986788568588423) D10 D13 D19 L0 +error(0.0006697986788568588423) D10 D13 D22 D37 L0 +error(0.001338700097173320998) D10 D13 D22 D40 L0 +error(0.0006697986788568588423) D10 D13 D22 L0 +error(0.001338700097173320998) D10 D13 D37 D40 L0 +error(0.002673815958446297981) D10 D13 L0 +error(0.0006697986788568588423) D10 D17 D19 D20 D22 D31 L0 +error(0.0006697986788568588423) D10 D17 D19 D20 D31 D40 L0 +error(0.0006697986788568588423) D10 D17 D19 D22 D31 L0 +error(0.0006697986788568588423) D10 D17 D19 D31 D40 L0 +error(0.004005357180252827609) D10 D17 D22 D31 D40 L0 +error(0.004005357180252827609) D10 D17 D31 L0 +error(0.001338700097173320998) D10 D19 D28 D36 +error(0.002673815958446297981) D10 D19 D28 D37 +error(0.001338700097173320998) D10 D19 D28 D37 D38 +error(0.0006697986788568588423) D10 D19 D28 D38 D40 +error(0.004669790293214320931) D10 D19 D28 D40 +error(0.0006697986788568588423) D10 D19 D29 D31 D37 D38 L0 +error(0.0006697986788568588423) D10 D19 D29 D31 D40 L0 +error(0.0006697986788568588423) D10 D19 D31 D37 L0 +error(0.0006697986788568588423) D10 D19 D31 D40 L0 +error(0.0006697986788568588423) D10 D20 D29 D31 D36 D37 L0 +error(0.0006697986788568588423) D10 D20 D29 D31 D36 D38 D40 L0 +error(0.0006697986788568588423) D10 D22 D31 D37 L0 +error(0.0006697986788568588423) D10 D22 D31 D40 L0 +error(0.006657753962803452177) D10 D28 +error(0.0006697986788568588423) D10 D28 D36 D37 +error(0.0006697986788568588423) D10 D28 D36 D37 D38 +error(0.001338700097173320998) D10 D28 D37 D38 D40 +error(0.001338700097173320998) D10 D28 D37 D40 +error(0.001338700097173320998) D10 D29 D31 D37 D38 D40 L0 +error(0.001338700097173320998) D10 D29 D31 L0 +error(0.001338700097173320998) D10 D31 D37 D40 L0 +error(0.001338700097173320998) D10 D31 L0 +error(0.0006697986788568588423) D11 D12 D14 D18 D20 D21 L0 +error(0.0006697986788568588423) D11 D12 D14 D18 D23 L0 +error(0.001338700097173320998) D11 D12 D14 D20 D21 D23 L0 +error(0.001338700097173320998) D11 D12 D14 D20 D21 D41 L0 +error(0.0006697986788568588423) D11 D12 D14 D20 D38 L0 +error(0.001338700097173320998) D11 D12 D14 D20 D39 D41 L0 +error(0.0006697986788568588423) D11 D12 D14 D21 D39 L0 +error(0.0006697986788568588423) D11 D12 D14 D23 D38 D39 L0 +error(0.001338700097173320998) D11 D12 D14 D23 D41 L0 +error(0.001338700097173320998) D11 D12 D14 D38 D39 D41 L0 +error(0.003340032800510209492) D11 D12 D14 L0 +error(0.0006697986788568588423) D11 D12 D16 D20 D21 D30 +error(0.0006697986788568588423) D11 D12 D16 D20 D21 D30 D41 +error(0.0006697986788568588423) D11 D12 D16 D20 D30 D39 +error(0.0006697986788568588423) D11 D12 D16 D20 D30 D39 D41 +error(0.001338700097173320998) D11 D12 D16 D21 D30 D39 +error(0.001338700097173320998) D11 D12 D16 D30 +error(0.0006697986788568588423) D11 D12 D18 D20 D21 L0 +error(0.0006697986788568588423) D11 D12 D18 L0 +error(0.001338700097173320998) D11 D12 D20 D21 L0 +error(0.0006697986788568588423) D11 D12 D20 D38 L0 +error(0.001338700097173320998) D11 D12 D20 D39 L0 +error(0.0006697986788568588423) D11 D12 D21 D32 D38 L0 +error(0.0006697986788568588423) D11 D12 D21 D32 D39 D41 L0 +error(0.0006697986788568588423) D11 D12 D21 D38 L0 +error(0.001338700097173320998) D11 D12 D21 D39 L0 +error(0.0006697986788568588423) D11 D12 D23 D32 D38 D39 L0 +error(0.0006697986788568588423) D11 D12 D23 D32 D41 L0 +error(0.001338700097173320998) D11 D12 D32 D38 D39 D41 L0 +error(0.001338700097173320998) D11 D12 D32 L0 +error(0.001338700097173320998) D11 D12 D38 D39 L0 +error(0.002673815958446297981) D11 D12 L0 +error(0.0006697986788568588423) D11 D13 D14 D18 D20 D22 L0 +error(0.0006697986788568588423) D11 D13 D14 D18 D23 L0 +error(0.001338700097173320998) D11 D13 D14 D20 D22 D23 L0 +error(0.001338700097173320998) D11 D13 D14 D20 D22 D41 L0 +error(0.0006697986788568588423) D11 D13 D14 D20 D38 L0 +error(0.001338700097173320998) D11 D13 D14 D20 D40 D41 L0 +error(0.0006697986788568588423) D11 D13 D14 D22 D40 L0 +error(0.0006697986788568588423) D11 D13 D14 D23 D38 D40 L0 +error(0.001338700097173320998) D11 D13 D14 D23 D41 L0 +error(0.001338700097173320998) D11 D13 D14 D38 D40 D41 L0 +error(0.003340032800510209492) D11 D13 D14 L0 +error(0.0006697986788568588423) D11 D13 D17 D19 D20 D22 D31 +error(0.0006697986788568588423) D11 D13 D17 D19 D20 D31 D40 +error(0.0006697986788568588423) D11 D13 D17 D20 D22 D31 D41 +error(0.0006697986788568588423) D11 D13 D17 D20 D31 D40 D41 +error(0.001338700097173320998) D11 D13 D17 D22 D31 D40 +error(0.001338700097173320998) D11 D13 D17 D31 +error(0.0006697986788568588423) D11 D13 D18 D19 D28 D38 L0 +error(0.0006697986788568588423) D11 D13 D18 D28 D37 D38 L0 +error(0.001338700097173320998) D11 D13 D19 D28 D37 L0 +error(0.0006697986788568588423) D11 D13 D19 D28 D38 D40 L0 +error(0.0006697986788568588423) D11 D13 D22 D32 D37 D38 L0 +error(0.0006697986788568588423) D11 D13 D22 D32 D37 D40 D41 L0 +error(0.0006697986788568588423) D11 D13 D23 D32 D38 D40 L0 +error(0.0006697986788568588423) D11 D13 D23 D32 D41 L0 +error(0.0006697986788568588423) D11 D13 D28 D37 D38 D40 L0 +error(0.001338700097173320998) D11 D13 D28 L0 +error(0.001338700097173320998) D11 D13 D32 D38 D40 D41 L0 +error(0.001338700097173320998) D11 D13 D32 L0 +error(0.0006697986788568588423) D11 D14 D18 D20 D29 +error(0.0006697986788568588423) D11 D14 D18 D29 D38 +error(0.001338700097173320998) D11 D14 D20 D29 D38 +error(0.0006697986788568588423) D11 D14 D20 D29 D39 +error(0.001338700097173320998) D11 D14 D29 +error(0.0006697986788568588423) D11 D14 D29 D38 D39 +error(0.004005357180252827609) D11 D18 D27 D36 L0 +error(0.0006697986788568588423) D11 D18 D27 D38 L0 +error(0.0006697986788568588423) D11 D18 D27 L0 +error(0.0006697986788568588423) D11 D20 D21 D23 D32 L0 +error(0.0006697986788568588423) D11 D20 D21 D32 D41 L0 +error(0.0006697986788568588423) D11 D20 D22 D23 D32 L0 +error(0.0006697986788568588423) D11 D20 D22 D32 D41 L0 +error(0.001338700097173320998) D11 D20 D29 D36 +error(0.001338700097173320998) D11 D20 D29 D36 D37 +error(0.001338700097173320998) D11 D20 D29 D36 D38 D39 +error(0.001338700097173320998) D11 D20 D29 D36 D38 D40 +error(0.004005357180252827609) D11 D20 D29 D36 D41 +error(0.002673815958446297981) D11 D20 D29 D38 +error(0.0006697986788568588423) D11 D20 D29 D39 D41 +error(0.0006697986788568588423) D11 D20 D29 D40 D41 +error(0.0006697986788568588423) D11 D20 D30 D32 D36 D38 D39 L0 +error(0.0006697986788568588423) D11 D20 D30 D32 D36 D41 L0 +error(0.0006697986788568588423) D11 D20 D30 D36 D38 D39 L0 +error(0.0006697986788568588423) D11 D20 D30 D36 L0 +error(0.0006697986788568588423) D11 D20 D31 D32 D36 D38 D40 L0 +error(0.0006697986788568588423) D11 D20 D31 D32 D36 D41 L0 +error(0.0006697986788568588423) D11 D21 D30 D32 D38 L0 +error(0.0006697986788568588423) D11 D21 D30 D32 D39 D41 L0 +error(0.0006697986788568588423) D11 D21 D30 D38 L0 +error(0.0006697986788568588423) D11 D21 D30 D39 L0 +error(0.0006697986788568588423) D11 D22 D31 D32 D37 D38 L0 +error(0.0006697986788568588423) D11 D22 D31 D32 D37 D40 D41 L0 +error(0.004005357180252827609) D11 D23 D32 D41 L0 +error(0.0006697986788568588423) D11 D27 D36 D38 L0 +error(0.0006697986788568588423) D11 D27 D36 L0 +error(0.004005357180252827609) D11 D27 L0 +error(0.007978628588222850399) D11 D29 +error(0.0006697986788568588423) D11 D29 D36 D37 D38 +error(0.0006697986788568588423) D11 D29 D36 D38 +error(0.0006697986788568588423) D11 D29 D37 D38 D40 +error(0.0006697986788568588423) D11 D29 D38 D39 +error(0.001338700097173320998) D11 D29 D38 D39 D41 +error(0.001338700097173320998) D11 D29 D38 D40 D41 +error(0.001338700097173320998) D11 D30 D32 D38 D39 D41 L0 +error(0.001338700097173320998) D11 D30 D32 L0 +error(0.001338700097173320998) D11 D30 D38 D39 L0 +error(0.001338700097173320998) D11 D30 L0 +error(0.001338700097173320998) D11 D31 D32 D38 D40 D41 L0 +error(0.001338700097173320998) D11 D31 D32 L0 +error(0.004005357180252827609) D11 D32 L0 +error(0.001338700097173320998) D12 D14 D16 D21 D23 D25 L0 +error(0.001338700097173320998) D12 D14 D16 D21 D23 D43 L0 +error(0.0006697986788568588423) D12 D14 D16 D21 D23 L0 +error(0.0006697986788568588423) D12 D14 D16 D21 D39 L0 +error(0.001338700097173320998) D12 D14 D16 D21 D41 D43 L0 +error(0.0006697986788568588423) D12 D14 D16 D23 D41 L0 +error(0.0006697986788568588423) D12 D14 D16 D25 D39 D41 L0 +error(0.001338700097173320998) D12 D14 D16 D25 D43 L0 +error(0.0006697986788568588423) D12 D14 D16 D25 L0 +error(0.001338700097173320998) D12 D14 D16 D39 D41 D43 L0 +error(0.003340032800510209492) D12 D14 D16 L0 +error(0.0006697986788568588423) D12 D14 D20 D21 D23 D32 +error(0.0006697986788568588423) D12 D14 D20 D21 D32 D41 +error(0.001338700097173320998) D12 D14 D20 D29 D38 L0 +error(0.0006697986788568588423) D12 D14 D20 D29 D39 D41 L0 +error(0.0006697986788568588423) D12 D14 D20 D29 D39 L0 +error(0.0006697986788568588423) D12 D14 D21 D23 D32 D43 +error(0.0006697986788568588423) D12 D14 D21 D32 D41 D43 +error(0.001338700097173320998) D12 D14 D23 D32 D41 +error(0.0006697986788568588423) D12 D14 D23 D34 D38 D39 L0 +error(0.0006697986788568588423) D12 D14 D23 D34 D38 D41 D43 L0 +error(0.0006697986788568588423) D12 D14 D25 D34 D39 D41 L0 +error(0.0006697986788568588423) D12 D14 D25 D34 D43 L0 +error(0.0006697986788568588423) D12 D14 D29 D38 D39 D41 L0 +error(0.0006697986788568588423) D12 D14 D29 D38 D39 L0 +error(0.001338700097173320998) D12 D14 D29 L0 +error(0.001338700097173320998) D12 D14 D32 +error(0.001338700097173320998) D12 D14 D34 D39 D41 D43 L0 +error(0.001338700097173320998) D12 D14 D34 L0 +error(0.0006697986788568588423) D12 D16 D21 D23 D25 D34 +error(0.0006697986788568588423) D12 D16 D21 D23 D34 D43 +error(0.0006697986788568588423) D12 D16 D21 D25 D34 +error(0.001338700097173320998) D12 D16 D21 D25 L0 +error(0.0006697986788568588423) D12 D16 D21 D34 D43 +error(0.0006697986788568588423) D12 D16 D21 D39 L0 +error(0.001338700097173320998) D12 D16 D21 D43 L0 +error(0.0006697986788568588423) D12 D16 D21 L0 +error(0.004005357180252827609) D12 D16 D25 D34 D43 +error(0.0006697986788568588423) D12 D16 D25 D39 L0 +error(0.001338700097173320998) D12 D16 D25 D43 L0 +error(0.0006697986788568588423) D12 D16 D25 L0 +error(0.004005357180252827609) D12 D16 D34 +error(0.001338700097173320998) D12 D16 D39 D43 L0 +error(0.002673815958446297981) D12 D16 L0 +error(0.001338700097173320998) D12 D21 D30 D38 +error(0.002673815958446297981) D12 D21 D30 D39 +error(0.001338700097173320998) D12 D21 D30 D39 D41 +error(0.0006697986788568588423) D12 D21 D30 D41 D43 +error(0.004669790293214320931) D12 D21 D30 D43 +error(0.0006697986788568588423) D12 D21 D32 D34 D39 D41 L0 +error(0.0006697986788568588423) D12 D21 D32 D34 D43 L0 +error(0.0006697986788568588423) D12 D21 D34 D39 L0 +error(0.0006697986788568588423) D12 D21 D34 D43 L0 +error(0.0006697986788568588423) D12 D23 D32 D34 D38 D39 L0 +error(0.0006697986788568588423) D12 D23 D32 D34 D38 D41 D43 L0 +error(0.0006697986788568588423) D12 D25 D34 D39 L0 +error(0.0006697986788568588423) D12 D25 D34 D43 L0 +error(0.006657753962803452177) D12 D30 +error(0.0006697986788568588423) D12 D30 D38 D39 +error(0.0006697986788568588423) D12 D30 D38 D39 D41 +error(0.001338700097173320998) D12 D30 D39 D41 D43 +error(0.001338700097173320998) D12 D30 D39 D43 +error(0.001338700097173320998) D12 D32 D34 D39 D41 D43 L0 +error(0.001338700097173320998) D12 D32 D34 L0 +error(0.001338700097173320998) D12 D34 D39 D43 L0 +error(0.001338700097173320998) D12 D34 L0 +error(0.0006697986788568588423) D13 D14 D17 D19 D22 D23 L0 +error(0.0006697986788568588423) D13 D14 D17 D19 D26 L0 +error(0.001338700097173320998) D13 D14 D17 D22 D23 D26 L0 +error(0.001338700097173320998) D13 D14 D17 D22 D23 D44 L0 +error(0.0006697986788568588423) D13 D14 D17 D22 D40 L0 +error(0.001338700097173320998) D13 D14 D17 D22 D41 D44 L0 +error(0.0006697986788568588423) D13 D14 D17 D23 D41 L0 +error(0.0006697986788568588423) D13 D14 D17 D26 D40 D41 L0 +error(0.001338700097173320998) D13 D14 D17 D26 D44 L0 +error(0.001338700097173320998) D13 D14 D17 D40 D41 D44 L0 +error(0.003340032800510209492) D13 D14 D17 L0 +error(0.0006697986788568588423) D13 D14 D19 D20 D29 D40 L0 +error(0.0006697986788568588423) D13 D14 D19 D29 D38 D40 L0 +error(0.0006697986788568588423) D13 D14 D20 D22 D23 D32 +error(0.0006697986788568588423) D13 D14 D20 D22 D32 D41 +error(0.001338700097173320998) D13 D14 D20 D29 D38 L0 +error(0.0006697986788568588423) D13 D14 D20 D29 D40 D41 L0 +error(0.0006697986788568588423) D13 D14 D22 D23 D32 D44 +error(0.0006697986788568588423) D13 D14 D22 D32 D41 D44 +error(0.001338700097173320998) D13 D14 D23 D32 D41 +error(0.0006697986788568588423) D13 D14 D23 D35 D38 D40 L0 +error(0.0006697986788568588423) D13 D14 D23 D35 D38 D41 D44 L0 +error(0.0006697986788568588423) D13 D14 D26 D35 D40 D41 L0 +error(0.0006697986788568588423) D13 D14 D26 D35 D44 L0 +error(0.0006697986788568588423) D13 D14 D29 D38 D40 D41 L0 +error(0.001338700097173320998) D13 D14 D29 L0 +error(0.001338700097173320998) D13 D14 D32 +error(0.001338700097173320998) D13 D14 D35 D40 D41 D44 L0 +error(0.001338700097173320998) D13 D14 D35 L0 +error(0.0006697986788568588423) D13 D15 D17 D19 D22 D24 L0 +error(0.0006697986788568588423) D13 D15 D17 D19 D26 L0 +error(0.001338700097173320998) D13 D15 D17 D22 D24 D26 L0 +error(0.001338700097173320998) D13 D15 D17 D22 D24 D44 L0 +error(0.0006697986788568588423) D13 D15 D17 D22 D40 L0 +error(0.001338700097173320998) D13 D15 D17 D22 D42 D44 L0 +error(0.0006697986788568588423) D13 D15 D17 D24 D42 L0 +error(0.0006697986788568588423) D13 D15 D17 D26 D40 D42 L0 +error(0.001338700097173320998) D13 D15 D17 D26 D44 L0 +error(0.001338700097173320998) D13 D15 D17 D40 D42 D44 L0 +error(0.003340032800510209492) D13 D15 D17 L0 +error(0.0006697986788568588423) D13 D15 D19 D22 D24 L0 +error(0.0006697986788568588423) D13 D15 D19 L0 +error(0.0006697986788568588423) D13 D15 D22 D24 D33 +error(0.0006697986788568588423) D13 D15 D22 D24 D33 D44 +error(0.001338700097173320998) D13 D15 D22 D24 L0 +error(0.0006697986788568588423) D13 D15 D22 D33 D42 +error(0.0006697986788568588423) D13 D15 D22 D33 D42 D44 +error(0.0006697986788568588423) D13 D15 D22 D40 L0 +error(0.001338700097173320998) D13 D15 D22 D42 L0 +error(0.001338700097173320998) D13 D15 D24 D33 D42 +error(0.0006697986788568588423) D13 D15 D24 D35 D40 L0 +error(0.0006697986788568588423) D13 D15 D24 D35 D42 D44 L0 +error(0.0006697986788568588423) D13 D15 D24 D40 L0 +error(0.001338700097173320998) D13 D15 D24 D42 L0 +error(0.0006697986788568588423) D13 D15 D26 D35 D40 D42 L0 +error(0.0006697986788568588423) D13 D15 D26 D35 D44 L0 +error(0.001338700097173320998) D13 D15 D33 +error(0.001338700097173320998) D13 D15 D35 D40 D42 D44 L0 +error(0.001338700097173320998) D13 D15 D35 L0 +error(0.001338700097173320998) D13 D15 D40 D42 L0 +error(0.002673815958446297981) D13 D15 L0 +error(0.0006697986788568588423) D13 D17 D19 D22 D31 +error(0.0006697986788568588423) D13 D17 D19 D31 D40 +error(0.0006697986788568588423) D13 D17 D22 D23 D26 D35 +error(0.0006697986788568588423) D13 D17 D22 D23 D35 D44 +error(0.0006697986788568588423) D13 D17 D22 D24 D26 D35 +error(0.0006697986788568588423) D13 D17 D22 D24 D35 D44 +error(0.001338700097173320998) D13 D17 D22 D31 D40 +error(0.0006697986788568588423) D13 D17 D22 D31 D42 +error(0.004005357180252827609) D13 D17 D26 D35 D44 +error(0.001338700097173320998) D13 D17 D31 +error(0.0006697986788568588423) D13 D17 D31 D40 D42 +error(0.004005357180252827609) D13 D17 D35 +error(0.0006697986788568588423) D13 D18 D19 D28 L0 +error(0.0006697986788568588423) D13 D18 D28 D37 L0 +error(0.004005357180252827609) D13 D19 D28 D37 L0 +error(0.0006697986788568588423) D13 D19 D28 D40 L0 +error(0.001338700097173320998) D13 D22 D31 D37 +error(0.001338700097173320998) D13 D22 D31 D37 D38 +error(0.001338700097173320998) D13 D22 D31 D37 D40 D41 +error(0.001338700097173320998) D13 D22 D31 D37 D40 D42 +error(0.004005357180252827609) D13 D22 D31 D37 D44 +error(0.002673815958446297981) D13 D22 D31 D40 +error(0.0006697986788568588423) D13 D22 D31 D41 D44 +error(0.0006697986788568588423) D13 D22 D31 D42 D44 +error(0.0006697986788568588423) D13 D22 D32 D35 D37 D40 D41 L0 +error(0.0006697986788568588423) D13 D22 D32 D35 D37 D44 L0 +error(0.0006697986788568588423) D13 D22 D33 D35 D37 D40 D42 L0 +error(0.0006697986788568588423) D13 D22 D33 D35 D37 D44 L0 +error(0.0006697986788568588423) D13 D22 D33 D37 D40 D42 L0 +error(0.0006697986788568588423) D13 D22 D33 D37 L0 +error(0.0006697986788568588423) D13 D23 D32 D35 D38 D40 L0 +error(0.0006697986788568588423) D13 D23 D32 D35 D38 D41 D44 L0 +error(0.0006697986788568588423) D13 D24 D33 D35 D40 L0 +error(0.0006697986788568588423) D13 D24 D33 D35 D42 D44 L0 +error(0.0006697986788568588423) D13 D24 D33 D40 L0 +error(0.0006697986788568588423) D13 D24 D33 D42 L0 +error(0.0006697986788568588423) D13 D28 D37 D40 L0 +error(0.004005357180252827609) D13 D28 L0 +error(0.007978628588222850399) D13 D31 +error(0.0006697986788568588423) D13 D31 D37 D38 D40 +error(0.0006697986788568588423) D13 D31 D37 D40 +error(0.0006697986788568588423) D13 D31 D38 D40 D41 +error(0.001338700097173320998) D13 D31 D40 D41 D44 +error(0.0006697986788568588423) D13 D31 D40 D42 +error(0.001338700097173320998) D13 D31 D40 D42 D44 +error(0.001338700097173320998) D13 D32 D35 D40 D41 D44 L0 +error(0.001338700097173320998) D13 D32 D35 L0 +error(0.001338700097173320998) D13 D33 D35 D40 D42 D44 L0 +error(0.001338700097173320998) D13 D33 D35 L0 +error(0.001338700097173320998) D13 D33 D40 D42 L0 +error(0.001338700097173320998) D13 D33 L0 +error(0.0006697986788568588423) D14 D16 D20 D21 D30 D41 L0 +error(0.0006697986788568588423) D14 D16 D20 D23 D25 L0 +error(0.0006697986788568588423) D14 D16 D20 D30 D39 D41 L0 +error(0.0006697986788568588423) D14 D16 D20 L0 +error(0.001338700097173320998) D14 D16 D21 D30 D39 L0 +error(0.0006697986788568588423) D14 D16 D21 D30 D41 D43 L0 +error(0.001338700097173320998) D14 D16 D23 D25 L0 +error(0.0006697986788568588423) D14 D16 D23 D41 L0 +error(0.001338700097173320998) D14 D16 D23 D43 L0 +error(0.0006697986788568588423) D14 D16 D25 D39 D41 L0 +error(0.0006697986788568588423) D14 D16 D25 D39 D43 L0 +error(0.0006697986788568588423) D14 D16 D25 D43 L0 +error(0.0006697986788568588423) D14 D16 D30 D39 D41 D43 L0 +error(0.001338700097173320998) D14 D16 D30 L0 +error(0.001338700097173320998) D14 D16 D41 D43 L0 +error(0.002673815958446297981) D14 D16 L0 +error(0.0006697986788568588423) D14 D17 D20 D22 D31 D41 L0 +error(0.0006697986788568588423) D14 D17 D20 D23 D26 L0 +error(0.0006697986788568588423) D14 D17 D20 D31 D40 D41 L0 +error(0.0006697986788568588423) D14 D17 D20 L0 +error(0.001338700097173320998) D14 D17 D22 D31 D40 L0 +error(0.0006697986788568588423) D14 D17 D22 D31 D41 D44 L0 +error(0.001338700097173320998) D14 D17 D23 D26 L0 +error(0.0006697986788568588423) D14 D17 D23 D41 L0 +error(0.001338700097173320998) D14 D17 D23 D44 L0 +error(0.0006697986788568588423) D14 D17 D26 D40 D41 L0 +error(0.0006697986788568588423) D14 D17 D26 D40 D44 L0 +error(0.0006697986788568588423) D14 D17 D26 D44 L0 +error(0.0006697986788568588423) D14 D17 D31 D40 D41 D44 L0 +error(0.001338700097173320998) D14 D17 D31 L0 +error(0.001338700097173320998) D14 D17 D41 D44 L0 +error(0.002673815958446297981) D14 D17 L0 +error(0.0006697986788568588423) D14 D21 D23 D25 D34 L0 +error(0.0006697986788568588423) D14 D21 D23 D34 D43 L0 +error(0.0006697986788568588423) D14 D22 D23 D26 D35 L0 +error(0.0006697986788568588423) D14 D22 D23 D35 D44 L0 +error(0.0006697986788568588423) D14 D23 D25 D34 L0 +error(0.0006697986788568588423) D14 D23 D26 D35 L0 +error(0.004005357180252827609) D14 D23 D32 D38 +error(0.001338700097173320998) D14 D23 D32 D38 D39 +error(0.001338700097173320998) D14 D23 D32 D38 D40 +error(0.001338700097173320998) D14 D23 D32 D38 D41 D43 +error(0.001338700097173320998) D14 D23 D32 D38 D41 D44 +error(0.002673815958446297981) D14 D23 D32 D41 +error(0.0006697986788568588423) D14 D23 D32 D43 +error(0.0006697986788568588423) D14 D23 D32 D44 +error(0.0006697986788568588423) D14 D23 D34 D38 D41 D43 L0 +error(0.0006697986788568588423) D14 D23 D34 D38 L0 +error(0.0006697986788568588423) D14 D23 D34 D43 L0 +error(0.0006697986788568588423) D14 D23 D35 D38 D41 D44 L0 +error(0.0006697986788568588423) D14 D23 D35 D38 L0 +error(0.0006697986788568588423) D14 D23 D35 D44 L0 +error(0.0006697986788568588423) D14 D25 D34 D39 D41 L0 +error(0.0006697986788568588423) D14 D25 D34 D39 D43 L0 +error(0.001338700097173320998) D14 D25 D34 D43 L0 +error(0.0006697986788568588423) D14 D26 D35 D40 D41 L0 +error(0.0006697986788568588423) D14 D26 D35 D40 D44 L0 +error(0.001338700097173320998) D14 D26 D35 D44 L0 +error(0.007978628588222850399) D14 D32 +error(0.0006697986788568588423) D14 D32 D38 D39 D41 +error(0.0006697986788568588423) D14 D32 D38 D40 D41 +error(0.0006697986788568588423) D14 D32 D39 D41 D43 +error(0.0006697986788568588423) D14 D32 D40 D41 D44 +error(0.001338700097173320998) D14 D32 D41 D43 +error(0.001338700097173320998) D14 D32 D41 D44 +error(0.001338700097173320998) D14 D34 D41 D43 L0 +error(0.002673815958446297981) D14 D34 L0 +error(0.001338700097173320998) D14 D35 D41 D44 L0 +error(0.002673815958446297981) D14 D35 L0 +error(0.001338700097173320998) D15 D17 D22 D31 D40 L0 +error(0.0006697986788568588423) D15 D17 D22 D31 D42 D44 L0 +error(0.0006697986788568588423) D15 D17 D22 D31 D42 L0 +error(0.002006705456917235505) D15 D17 D24 D26 L0 +error(0.0006697986788568588423) D15 D17 D24 D42 L0 +error(0.001338700097173320998) D15 D17 D24 D44 L0 +error(0.0006697986788568588423) D15 D17 D26 D40 D42 L0 +error(0.0006697986788568588423) D15 D17 D26 D40 D44 L0 +error(0.0006697986788568588423) D15 D17 D26 D44 L0 +error(0.0006697986788568588423) D15 D17 D31 D40 D42 D44 L0 +error(0.0006697986788568588423) D15 D17 D31 D40 D42 L0 +error(0.001338700097173320998) D15 D17 D31 L0 +error(0.001338700097173320998) D15 D17 D42 D44 L0 +error(0.003340032800510209492) D15 D17 L0 +error(0.0006697986788568588423) D15 D22 D24 D26 D35 L0 +error(0.0006697986788568588423) D15 D22 D24 D35 D44 L0 +error(0.0006697986788568588423) D15 D24 D26 D35 L0 +error(0.004669790293214320931) D15 D24 D33 +error(0.001338700097173320998) D15 D24 D33 D40 +error(0.002673815958446297981) D15 D24 D33 D42 +error(0.001338700097173320998) D15 D24 D33 D42 D44 +error(0.0006697986788568588423) D15 D24 D33 D44 +error(0.0006697986788568588423) D15 D24 D35 D42 D44 L0 +error(0.0006697986788568588423) D15 D24 D35 D44 L0 +error(0.0006697986788568588423) D15 D24 D35 L0 +error(0.001338700097173320998) D15 D24 D42 L0 +error(0.007978628588222850399) D15 D24 L0 +error(0.0006697986788568588423) D15 D26 D35 D40 D42 L0 +error(0.0006697986788568588423) D15 D26 D35 D40 D44 L0 +error(0.001338700097173320998) D15 D26 D35 D44 L0 +error(0.006657753962803452177) D15 D33 +error(0.0006697986788568588423) D15 D33 D40 D42 +error(0.0006697986788568588423) D15 D33 D40 D42 D44 +error(0.001338700097173320998) D15 D33 D42 +error(0.001338700097173320998) D15 D33 D42 D44 +error(0.001338700097173320998) D15 D35 D42 D44 L0 +error(0.002673815958446297981) D15 D35 L0 +error(0.001338700097173320998) D15 D42 L0 +error(0.007978628588222850399) D15 L0 +error(0.0006697986788568588423) D16 D20 D21 D30 L0 +error(0.0006697986788568588423) D16 D20 D30 D39 L0 +error(0.0006697986788568588423) D16 D21 D23 D32 D43 L0 +error(0.0006697986788568588423) D16 D21 D25 L0 +error(0.004005357180252827609) D16 D21 D30 D39 L0 +error(0.0006697986788568588423) D16 D21 D30 D43 L0 +error(0.0006697986788568588423) D16 D21 D32 D41 D43 L0 +error(0.0006697986788568588423) D16 D21 L0 +error(0.0006697986788568588423) D16 D23 D25 D34 +error(0.001338700097173320998) D16 D23 D32 D41 L0 +error(0.0006697986788568588423) D16 D23 D32 D43 L0 +error(0.0006697986788568588423) D16 D23 D34 D43 +error(0.0006697986788568588423) D16 D25 D34 +error(0.001338700097173320998) D16 D25 D34 D39 +error(0.001338700097173320998) D16 D25 D34 D39 D41 +error(0.004005357180252827609) D16 D25 D34 D39 D43 +error(0.002673815958446297981) D16 D25 D34 D43 +error(0.0006697986788568588423) D16 D25 D39 D43 L0 +error(0.0006697986788568588423) D16 D25 D39 L0 +error(0.0006697986788568588423) D16 D25 D43 L0 +error(0.004005357180252827609) D16 D25 L0 +error(0.0006697986788568588423) D16 D30 D39 D43 L0 +error(0.004005357180252827609) D16 D30 L0 +error(0.0006697986788568588423) D16 D32 D41 D43 L0 +error(0.001338700097173320998) D16 D32 L0 +error(0.006657753962803452177) D16 D34 +error(0.0006697986788568588423) D16 D34 D39 D41 D43 +error(0.0006697986788568588423) D16 D34 D39 D43 +error(0.0006697986788568588423) D16 D34 D41 D43 +error(0.001338700097173320998) D16 D34 D43 +error(0.001338700097173320998) D16 D43 L0 +error(0.004669790293214320931) D16 L0 +error(0.0006697986788568588423) D17 D22 D23 D32 D44 L0 +error(0.0006697986788568588423) D17 D22 D24 D33 D44 L0 +error(0.0006697986788568588423) D17 D22 D32 D41 D44 L0 +error(0.0006697986788568588423) D17 D22 D33 D42 D44 L0 +error(0.0006697986788568588423) D17 D23 D26 D35 +error(0.001338700097173320998) D17 D23 D32 D41 L0 +error(0.0006697986788568588423) D17 D23 D32 D44 L0 +error(0.0006697986788568588423) D17 D23 D35 D44 +error(0.0006697986788568588423) D17 D24 D26 D35 +error(0.001338700097173320998) D17 D24 D33 D42 L0 +error(0.0006697986788568588423) D17 D24 D33 D44 L0 +error(0.0006697986788568588423) D17 D24 D35 D44 +error(0.001338700097173320998) D17 D26 D35 D40 D41 +error(0.001338700097173320998) D17 D26 D35 D40 D42 +error(0.004005357180252827609) D17 D26 D35 D40 D44 +error(0.002673815958446297981) D17 D26 D35 D44 +error(0.0006697986788568588423) D17 D32 D41 D44 L0 +error(0.001338700097173320998) D17 D32 L0 +error(0.0006697986788568588423) D17 D33 D42 D44 L0 +error(0.001338700097173320998) D17 D33 L0 +error(0.006657753962803452177) D17 D35 +error(0.0006697986788568588423) D17 D35 D40 D41 D44 +error(0.0006697986788568588423) D17 D35 D40 D42 D44 +error(0.0006697986788568588423) D17 D35 D41 D44 +error(0.0006697986788568588423) D17 D35 D42 D44 +error(0.01257390183676828158) D18 +error(0.005333333333333313206) D18 D19 +error(0.003340032800510209492) D18 D19 D20 +error(0.001338700097173320998) D18 D19 D38 +error(0.002673815958446297981) D18 D20 +error(0.001338700097173320998) D18 D20 D21 +error(0.001338700097173320998) D18 D20 D22 +error(0.004005357180252827609) D18 D23 +error(0.0006697986788568588423) D18 D27 D28 D29 D36 D37 L0 +error(0.0006697986788568588423) D18 D27 D28 D29 D38 L0 +error(0.0006697986788568588423) D18 D27 D28 D36 D37 L0 +error(0.0006697986788568588423) D18 D27 D28 L0 +error(0.0006697986788568588423) D18 D27 D29 D36 L0 +error(0.0006697986788568588423) D18 D27 D29 D38 L0 +error(0.0006697986788568588423) D18 D27 D36 L0 +error(0.0006697986788568588423) D18 D27 L0 +error(0.006657753962803452177) D18 D36 +error(0.001338700097173320998) D18 D36 D37 +error(0.001338700097173320998) D18 D37 +error(0.001338700097173320998) D18 D37 D38 +error(0.005333333333333313206) D18 D38 +error(0.009295966703663446212) D19 +error(0.004005357180252827609) D19 D20 +error(0.003340032800510209492) D19 D20 D22 +error(0.001338700097173320998) D19 D20 D40 +error(0.002673815958446297981) D19 D22 +error(0.001338700097173320998) D19 D22 D23 +error(0.001338700097173320998) D19 D22 D24 +error(0.004005357180252827609) D19 D26 +error(0.0006697986788568588423) D19 D28 D29 D31 D37 D38 L0 +error(0.0006697986788568588423) D19 D28 D29 D31 D40 L0 +error(0.0006697986788568588423) D19 D28 D31 D37 L0 +error(0.0006697986788568588423) D19 D28 D31 D40 L0 +error(0.001338700097173320998) D19 D36 +error(0.006657753962803452177) D19 D37 +error(0.001338700097173320998) D19 D37 D38 +error(0.001338700097173320998) D19 D38 D40 +error(0.005333333333333313206) D19 D40 +error(0.01970848819953020456) D20 +error(0.004005357180252827609) D20 D21 +error(0.003340032800510209492) D20 D21 D23 +error(0.001338700097173320998) D20 D21 D41 +error(0.002673815958446297981) D20 D22 +error(0.003340032800510209492) D20 D22 D23 +error(0.001338700097173320998) D20 D22 D41 +error(0.001338700097173320998) D20 D23 D25 +error(0.001338700097173320998) D20 D23 D26 +error(0.0006697986788568588423) D20 D29 D30 D32 D36 D38 D39 L0 +error(0.0006697986788568588423) D20 D29 D30 D32 D36 D41 L0 +error(0.0006697986788568588423) D20 D29 D30 D36 D38 D39 L0 +error(0.0006697986788568588423) D20 D29 D30 D36 L0 +error(0.0006697986788568588423) D20 D29 D31 D32 D36 D38 D40 L0 +error(0.0006697986788568588423) D20 D29 D31 D32 D36 D41 L0 +error(0.001338700097173320998) D20 D36 +error(0.001338700097173320998) D20 D36 D37 +error(0.001338700097173320998) D20 D36 D38 D39 +error(0.001338700097173320998) D20 D36 D38 D40 +error(0.004005357180252827609) D20 D36 D41 +error(0.007978628588222850399) D20 D38 +error(0.001338700097173320998) D20 D39 +error(0.001338700097173320998) D20 D39 D41 +error(0.001338700097173320998) D20 D40 D41 +error(0.009295966703663446212) D21 +error(0.004005357180252827609) D21 D23 +error(0.003340032800510209492) D21 D23 D25 +error(0.001338700097173320998) D21 D23 D43 +error(0.006657753962803452177) D21 D25 +error(0.0006697986788568588423) D21 D25 D34 L0 +error(0.0006697986788568588423) D21 D30 D32 D34 D39 D41 L0 +error(0.0006697986788568588423) D21 D30 D32 D34 D43 L0 +error(0.0006697986788568588423) D21 D30 D34 D39 L0 +error(0.0006697986788568588423) D21 D30 D34 D43 L0 +error(0.0006697986788568588423) D21 D34 D43 L0 +error(0.001338700097173320998) D21 D38 +error(0.006657753962803452177) D21 D39 +error(0.001338700097173320998) D21 D39 D41 +error(0.001338700097173320998) D21 D41 D43 +error(0.005333333333333313206) D21 D43 +error(0.01582994014814808822) D22 +error(0.002673815958446297981) D22 D23 +error(0.003340032800510209492) D22 D23 D26 +error(0.001338700097173320998) D22 D23 D44 +error(0.004005357180252827609) D22 D24 +error(0.003340032800510209492) D22 D24 D26 +error(0.0006697986788568588423) D22 D24 D33 L0 +error(0.001338700097173320998) D22 D24 D44 +error(0.004005357180252827609) D22 D26 +error(0.0006697986788568588423) D22 D31 D32 D35 D37 D40 D41 L0 +error(0.0006697986788568588423) D22 D31 D32 D35 D37 D44 L0 +error(0.0006697986788568588423) D22 D31 D33 D35 D37 D40 D42 L0 +error(0.0006697986788568588423) D22 D31 D33 D35 D37 D44 L0 +error(0.0006697986788568588423) D22 D31 D33 D37 D40 D42 L0 +error(0.0006697986788568588423) D22 D31 D33 D37 L0 +error(0.0006697986788568588423) D22 D33 D42 L0 +error(0.001338700097173320998) D22 D37 +error(0.001338700097173320998) D22 D37 D38 +error(0.001338700097173320998) D22 D37 D40 D41 +error(0.001338700097173320998) D22 D37 D40 D42 +error(0.004005357180252827609) D22 D37 D44 +error(0.007978628588222850399) D22 D40 +error(0.001338700097173320998) D22 D41 D44 +error(0.001338700097173320998) D22 D42 +error(0.001338700097173320998) D22 D42 D44 +error(0.01060977777777773884) D23 +error(0.004005357180252827609) D23 D25 +error(0.004005357180252827609) D23 D26 +error(0.0006697986788568588423) D23 D32 D34 D38 D41 D43 L0 +error(0.0006697986788568588423) D23 D32 D34 D38 L0 +error(0.0006697986788568588423) D23 D32 D35 D38 D41 D44 L0 +error(0.0006697986788568588423) D23 D32 D35 D38 L0 +error(0.004005357180252827609) D23 D38 +error(0.001338700097173320998) D23 D38 D39 +error(0.001338700097173320998) D23 D38 D40 +error(0.001338700097173320998) D23 D38 D41 D43 +error(0.001338700097173320998) D23 D38 D41 D44 +error(0.007978628588222850399) D23 D41 +error(0.001338700097173320998) D23 D43 +error(0.001338700097173320998) D23 D44 +error(0.01387893656672014447) D24 +error(0.005333333333333313206) D24 D26 +error(0.0006697986788568588423) D24 D33 D35 D42 D44 L0 +error(0.0006697986788568588423) D24 D33 D35 L0 +error(0.004669790293214320931) D24 D33 D42 L0 +error(0.001338700097173320998) D24 D33 L0 +error(0.001338700097173320998) D24 D40 +error(0.006657753962803452177) D24 D42 +error(0.001338700097173320998) D24 D42 D44 +error(0.001338700097173320998) D24 D44 +error(0.01647853308100971984) D25 +error(0.0006697986788568588423) D25 D34 D39 D43 L0 +error(0.0006697986788568588423) D25 D34 D39 L0 +error(0.001338700097173320998) D25 D34 D43 L0 +error(0.0006697986788568588423) D25 D34 L0 +error(0.001338700097173320998) D25 D39 +error(0.001338700097173320998) D25 D39 D41 +error(0.004005357180252827609) D25 D39 D43 +error(0.006657753962803452177) D25 D43 +error(0.01192007125386686239) D26 +error(0.001338700097173320998) D26 D40 D41 +error(0.001338700097173320998) D26 D40 D42 +error(0.004005357180252827609) D26 D40 D44 +error(0.006657753962803452177) D26 D44 +error(0.001338700097173320998) D27 D28 D29 D36 D37 D38 L0 +error(0.001338700097173320998) D27 D28 D29 D36 D37 D56 L0 +error(0.0006697986788568588423) D27 D28 D29 D36 D54 L0 +error(0.001338700097173320998) D27 D28 D29 D36 D55 D56 L0 +error(0.0006697986788568588423) D27 D28 D29 D37 D55 L0 +error(0.0006697986788568588423) D27 D28 D29 D38 D54 D55 L0 +error(0.001338700097173320998) D27 D28 D29 D38 D56 L0 +error(0.001338700097173320998) D27 D28 D29 D54 D55 D56 L0 +error(0.003340032800510209492) D27 D28 D29 L0 +error(0.0006697986788568588423) D27 D28 D31 D36 D37 D46 +error(0.0006697986788568588423) D27 D28 D31 D36 D37 D46 D56 +error(0.0006697986788568588423) D27 D28 D31 D36 D46 D55 +error(0.0006697986788568588423) D27 D28 D31 D36 D46 D55 D56 +error(0.001338700097173320998) D27 D28 D31 D37 D46 D55 +error(0.001338700097173320998) D27 D28 D31 D46 +error(0.001338700097173320998) D27 D28 D36 D37 L0 +error(0.0006697986788568588423) D27 D28 D36 D54 L0 +error(0.001338700097173320998) D27 D28 D36 D55 L0 +error(0.0006697986788568588423) D27 D28 D37 D47 D54 L0 +error(0.0006697986788568588423) D27 D28 D37 D47 D55 D56 L0 +error(0.0006697986788568588423) D27 D28 D37 D54 L0 +error(0.001338700097173320998) D27 D28 D37 D55 L0 +error(0.0006697986788568588423) D27 D28 D38 D47 D54 D55 L0 +error(0.0006697986788568588423) D27 D28 D38 D47 D56 L0 +error(0.001338700097173320998) D27 D28 D47 D54 D55 D56 L0 +error(0.001338700097173320998) D27 D28 D47 L0 +error(0.001338700097173320998) D27 D28 D54 D55 L0 +error(0.002673815958446297981) D27 D28 L0 +error(0.001338700097173320998) D27 D29 D36 D38 L0 +error(0.0006697986788568588423) D27 D29 D36 D45 +error(0.001338700097173320998) D27 D29 D36 D45 D54 +error(0.0006697986788568588423) D27 D29 D36 D45 D55 +error(0.0006697986788568588423) D27 D29 D36 D54 L0 +error(0.001338700097173320998) D27 D29 D36 D56 L0 +error(0.0006697986788568588423) D27 D29 D38 D54 L0 +error(0.001338700097173320998) D27 D29 D38 D56 L0 +error(0.001338700097173320998) D27 D29 D45 +error(0.0006697986788568588423) D27 D29 D45 D54 +error(0.0006697986788568588423) D27 D29 D45 D54 D55 +error(0.001338700097173320998) D27 D29 D54 D56 L0 +error(0.002673815958446297981) D27 D29 L0 +error(0.0006697986788568588423) D27 D32 D36 D37 D38 D47 L0 +error(0.0006697986788568588423) D27 D32 D36 D37 D47 D56 L0 +error(0.0006697986788568588423) D27 D32 D36 D38 D47 L0 +error(0.0006697986788568588423) D27 D32 D36 D47 D56 L0 +error(0.004005357180252827609) D27 D32 D38 D47 D56 L0 +error(0.004005357180252827609) D27 D32 D47 L0 +error(0.001338700097173320998) D27 D36 D45 +error(0.002673815958446297981) D27 D36 D45 D54 +error(0.001338700097173320998) D27 D36 D45 D54 D55 +error(0.0006697986788568588423) D27 D36 D45 D55 D56 +error(0.004669790293214320931) D27 D36 D45 D56 +error(0.0006697986788568588423) D27 D36 D46 D47 D54 D55 L0 +error(0.0006697986788568588423) D27 D36 D46 D47 D56 L0 +error(0.0006697986788568588423) D27 D36 D46 D54 D55 L0 +error(0.0006697986788568588423) D27 D36 D46 L0 +error(0.0006697986788568588423) D27 D36 D47 D54 L0 +error(0.0006697986788568588423) D27 D36 D47 D56 L0 +error(0.001338700097173320998) D27 D36 D54 L0 +error(0.002006705456917235505) D27 D36 L0 +error(0.0006697986788568588423) D27 D37 D46 D47 D54 L0 +error(0.0006697986788568588423) D27 D37 D46 D47 D55 D56 L0 +error(0.0006697986788568588423) D27 D37 D46 D54 L0 +error(0.0006697986788568588423) D27 D37 D46 D55 L0 +error(0.0006697986788568588423) D27 D38 D47 D54 L0 +error(0.0006697986788568588423) D27 D38 D47 D56 L0 +error(0.006657753962803452177) D27 D45 +error(0.0006697986788568588423) D27 D45 D54 +error(0.0006697986788568588423) D27 D45 D54 D55 +error(0.001338700097173320998) D27 D45 D54 D55 D56 +error(0.001338700097173320998) D27 D45 D54 D56 +error(0.001338700097173320998) D27 D46 D47 D54 D55 D56 L0 +error(0.001338700097173320998) D27 D46 D47 L0 +error(0.001338700097173320998) D27 D46 D54 D55 L0 +error(0.001338700097173320998) D27 D46 L0 +error(0.001338700097173320998) D27 D47 D54 D56 L0 +error(0.001338700097173320998) D27 D47 L0 +error(0.001338700097173320998) D27 D54 L0 +error(0.002006705456917235505) D27 L0 +error(0.001338700097173320998) D28 D29 D31 D37 D38 D40 L0 +error(0.001338700097173320998) D28 D29 D31 D37 D38 D58 L0 +error(0.0006697986788568588423) D28 D29 D31 D37 D55 L0 +error(0.001338700097173320998) D28 D29 D31 D37 D56 D58 L0 +error(0.0006697986788568588423) D28 D29 D31 D38 D56 L0 +error(0.0006697986788568588423) D28 D29 D31 D40 D55 D56 L0 +error(0.001338700097173320998) D28 D29 D31 D40 D58 L0 +error(0.001338700097173320998) D28 D29 D31 D55 D56 D58 L0 +error(0.003340032800510209492) D28 D29 D31 L0 +error(0.0006697986788568588423) D28 D29 D32 D36 D37 D38 D47 +error(0.0006697986788568588423) D28 D29 D32 D36 D37 D47 D56 +error(0.0006697986788568588423) D28 D29 D32 D37 D38 D47 D58 +error(0.0006697986788568588423) D28 D29 D32 D37 D47 D56 D58 +error(0.001338700097173320998) D28 D29 D32 D38 D47 D56 +error(0.001338700097173320998) D28 D29 D32 D47 +error(0.001338700097173320998) D28 D29 D36 D45 D54 L0 +error(0.0006697986788568588423) D28 D29 D36 D45 D55 D56 L0 +error(0.0006697986788568588423) D28 D29 D36 D45 D55 L0 +error(0.0006697986788568588423) D28 D29 D38 D49 D54 D55 L0 +error(0.0006697986788568588423) D28 D29 D38 D49 D54 D56 D58 L0 +error(0.0006697986788568588423) D28 D29 D40 D49 D55 D56 L0 +error(0.0006697986788568588423) D28 D29 D40 D49 D58 L0 +error(0.0006697986788568588423) D28 D29 D45 D54 D55 D56 L0 +error(0.0006697986788568588423) D28 D29 D45 D54 D55 L0 +error(0.001338700097173320998) D28 D29 D45 L0 +error(0.001338700097173320998) D28 D29 D49 D55 D56 D58 L0 +error(0.001338700097173320998) D28 D29 D49 L0 +error(0.001338700097173320998) D28 D31 D37 D40 L0 +error(0.0006697986788568588423) D28 D31 D37 D55 L0 +error(0.001338700097173320998) D28 D31 D37 D58 L0 +error(0.0006697986788568588423) D28 D31 D40 D55 L0 +error(0.001338700097173320998) D28 D31 D40 D58 L0 +error(0.001338700097173320998) D28 D31 D55 D58 L0 +error(0.002673815958446297981) D28 D31 L0 +error(0.0006697986788568588423) D28 D35 D37 D38 D40 D49 L0 +error(0.0006697986788568588423) D28 D35 D37 D38 D49 D58 L0 +error(0.0006697986788568588423) D28 D35 D37 D40 D49 L0 +error(0.0006697986788568588423) D28 D35 D37 D49 D58 L0 +error(0.004005357180252827609) D28 D35 D40 D49 D58 L0 +error(0.004005357180252827609) D28 D35 D49 L0 +error(0.001338700097173320998) D28 D37 D46 D54 +error(0.002673815958446297981) D28 D37 D46 D55 +error(0.001338700097173320998) D28 D37 D46 D55 D56 +error(0.0006697986788568588423) D28 D37 D46 D56 D58 +error(0.004669790293214320931) D28 D37 D46 D58 +error(0.0006697986788568588423) D28 D37 D47 D49 D55 D56 L0 +error(0.0006697986788568588423) D28 D37 D47 D49 D58 L0 +error(0.0006697986788568588423) D28 D37 D49 D55 L0 +error(0.0006697986788568588423) D28 D37 D49 D58 L0 +error(0.0006697986788568588423) D28 D38 D47 D49 D54 D55 L0 +error(0.0006697986788568588423) D28 D38 D47 D49 D54 D56 D58 L0 +error(0.0006697986788568588423) D28 D40 D49 D55 L0 +error(0.0006697986788568588423) D28 D40 D49 D58 L0 +error(0.006657753962803452177) D28 D46 +error(0.0006697986788568588423) D28 D46 D54 D55 +error(0.0006697986788568588423) D28 D46 D54 D55 D56 +error(0.001338700097173320998) D28 D46 D55 D56 D58 +error(0.001338700097173320998) D28 D46 D55 D58 +error(0.001338700097173320998) D28 D47 D49 D55 D56 D58 L0 +error(0.001338700097173320998) D28 D47 D49 L0 +error(0.001338700097173320998) D28 D49 D55 D58 L0 +error(0.001338700097173320998) D28 D49 L0 +error(0.001338700097173320998) D29 D30 D32 D38 D39 D41 L0 +error(0.001338700097173320998) D29 D30 D32 D38 D39 D59 L0 +error(0.0006697986788568588423) D29 D30 D32 D38 D56 L0 +error(0.001338700097173320998) D29 D30 D32 D38 D57 D59 L0 +error(0.0006697986788568588423) D29 D30 D32 D39 D57 L0 +error(0.0006697986788568588423) D29 D30 D32 D41 D56 D57 L0 +error(0.001338700097173320998) D29 D30 D32 D41 D59 L0 +error(0.001338700097173320998) D29 D30 D32 D56 D57 D59 L0 +error(0.003340032800510209492) D29 D30 D32 L0 +error(0.0006697986788568588423) D29 D30 D34 D38 D39 D48 +error(0.0006697986788568588423) D29 D30 D34 D38 D39 D48 D59 +error(0.0006697986788568588423) D29 D30 D34 D38 D48 D57 +error(0.0006697986788568588423) D29 D30 D34 D38 D48 D57 D59 +error(0.001338700097173320998) D29 D30 D34 D39 D48 D57 +error(0.001338700097173320998) D29 D30 D34 D48 +error(0.001338700097173320998) D29 D30 D38 D39 L0 +error(0.0006697986788568588423) D29 D30 D38 D56 L0 +error(0.001338700097173320998) D29 D30 D38 D57 L0 +error(0.0006697986788568588423) D29 D30 D39 D50 D56 L0 +error(0.0006697986788568588423) D29 D30 D39 D50 D57 D59 L0 +error(0.0006697986788568588423) D29 D30 D39 D56 L0 +error(0.001338700097173320998) D29 D30 D39 D57 L0 +error(0.0006697986788568588423) D29 D30 D41 D50 D56 D57 L0 +error(0.0006697986788568588423) D29 D30 D41 D50 D59 L0 +error(0.001338700097173320998) D29 D30 D50 D56 D57 D59 L0 +error(0.001338700097173320998) D29 D30 D50 L0 +error(0.001338700097173320998) D29 D30 D56 D57 L0 +error(0.002673815958446297981) D29 D30 L0 +error(0.001338700097173320998) D29 D31 D32 D38 D40 D41 L0 +error(0.001338700097173320998) D29 D31 D32 D38 D40 D59 L0 +error(0.0006697986788568588423) D29 D31 D32 D38 D56 L0 +error(0.001338700097173320998) D29 D31 D32 D38 D58 D59 L0 +error(0.0006697986788568588423) D29 D31 D32 D40 D58 L0 +error(0.0006697986788568588423) D29 D31 D32 D41 D56 D58 L0 +error(0.001338700097173320998) D29 D31 D32 D41 D59 L0 +error(0.001338700097173320998) D29 D31 D32 D56 D58 D59 L0 +error(0.003340032800510209492) D29 D31 D32 L0 +error(0.0006697986788568588423) D29 D31 D35 D37 D38 D40 D49 +error(0.0006697986788568588423) D29 D31 D35 D37 D38 D49 D58 +error(0.0006697986788568588423) D29 D31 D35 D38 D40 D49 D59 +error(0.0006697986788568588423) D29 D31 D35 D38 D49 D58 D59 +error(0.001338700097173320998) D29 D31 D35 D40 D49 D58 +error(0.001338700097173320998) D29 D31 D35 D49 +error(0.0006697986788568588423) D29 D31 D36 D37 D46 D56 L0 +error(0.0006697986788568588423) D29 D31 D36 D46 D55 D56 L0 +error(0.001338700097173320998) D29 D31 D37 D46 D55 L0 +error(0.0006697986788568588423) D29 D31 D37 D46 D56 D58 L0 +error(0.0006697986788568588423) D29 D31 D40 D50 D55 D56 L0 +error(0.0006697986788568588423) D29 D31 D40 D50 D55 D58 D59 L0 +error(0.0006697986788568588423) D29 D31 D41 D50 D56 D58 L0 +error(0.0006697986788568588423) D29 D31 D41 D50 D59 L0 +error(0.0006697986788568588423) D29 D31 D46 D55 D56 D58 L0 +error(0.001338700097173320998) D29 D31 D46 L0 +error(0.001338700097173320998) D29 D31 D50 D56 D58 D59 L0 +error(0.001338700097173320998) D29 D31 D50 L0 +error(0.0006697986788568588423) D29 D32 D36 D38 D47 +error(0.0006697986788568588423) D29 D32 D36 D47 D56 +error(0.001338700097173320998) D29 D32 D38 D47 D56 +error(0.0006697986788568588423) D29 D32 D38 D47 D57 +error(0.001338700097173320998) D29 D32 D47 +error(0.0006697986788568588423) D29 D32 D47 D56 D57 +error(0.004005357180252827609) D29 D36 D45 D54 L0 +error(0.0006697986788568588423) D29 D36 D45 D56 L0 +error(0.0006697986788568588423) D29 D36 D45 L0 +error(0.0006697986788568588423) D29 D38 D39 D41 D50 L0 +error(0.0006697986788568588423) D29 D38 D39 D50 D59 L0 +error(0.0006697986788568588423) D29 D38 D40 D41 D50 L0 +error(0.0006697986788568588423) D29 D38 D40 D50 D59 L0 +error(0.001338700097173320998) D29 D38 D47 D54 +error(0.001338700097173320998) D29 D38 D47 D54 D55 +error(0.001338700097173320998) D29 D38 D47 D54 D56 D57 +error(0.001338700097173320998) D29 D38 D47 D54 D56 D58 +error(0.004005357180252827609) D29 D38 D47 D54 D59 +error(0.002673815958446297981) D29 D38 D47 D56 +error(0.0006697986788568588423) D29 D38 D47 D57 D59 +error(0.0006697986788568588423) D29 D38 D47 D58 D59 +error(0.0006697986788568588423) D29 D38 D48 D50 D54 D56 D57 L0 +error(0.0006697986788568588423) D29 D38 D48 D50 D54 D59 L0 +error(0.0006697986788568588423) D29 D38 D48 D54 D56 D57 L0 +error(0.0006697986788568588423) D29 D38 D48 D54 L0 +error(0.0006697986788568588423) D29 D38 D49 D50 D54 D56 D58 L0 +error(0.0006697986788568588423) D29 D38 D49 D50 D54 D59 L0 +error(0.0006697986788568588423) D29 D39 D48 D50 D56 L0 +error(0.0006697986788568588423) D29 D39 D48 D50 D57 D59 L0 +error(0.0006697986788568588423) D29 D39 D48 D56 L0 +error(0.0006697986788568588423) D29 D39 D48 D57 L0 +error(0.0006697986788568588423) D29 D40 D49 D50 D55 D56 L0 +error(0.0006697986788568588423) D29 D40 D49 D50 D55 D58 D59 L0 +error(0.004005357180252827609) D29 D41 D50 D59 L0 +error(0.0006697986788568588423) D29 D45 D54 D56 L0 +error(0.0006697986788568588423) D29 D45 D54 L0 +error(0.004005357180252827609) D29 D45 L0 +error(0.007978628588222850399) D29 D47 +error(0.0006697986788568588423) D29 D47 D54 D55 D56 +error(0.0006697986788568588423) D29 D47 D54 D56 +error(0.0006697986788568588423) D29 D47 D55 D56 D58 +error(0.0006697986788568588423) D29 D47 D56 D57 +error(0.001338700097173320998) D29 D47 D56 D57 D59 +error(0.001338700097173320998) D29 D47 D56 D58 D59 +error(0.001338700097173320998) D29 D48 D50 D56 D57 D59 L0 +error(0.001338700097173320998) D29 D48 D50 L0 +error(0.001338700097173320998) D29 D48 D56 D57 L0 +error(0.001338700097173320998) D29 D48 L0 +error(0.001338700097173320998) D29 D49 D50 D56 D58 D59 L0 +error(0.001338700097173320998) D29 D49 D50 L0 +error(0.004005357180252827609) D29 D50 L0 +error(0.001338700097173320998) D30 D32 D34 D39 D41 D43 L0 +error(0.001338700097173320998) D30 D32 D34 D39 D41 D61 L0 +error(0.0006697986788568588423) D30 D32 D34 D39 D57 L0 +error(0.001338700097173320998) D30 D32 D34 D39 D59 D61 L0 +error(0.0006697986788568588423) D30 D32 D34 D41 D59 L0 +error(0.0006697986788568588423) D30 D32 D34 D43 D57 D59 L0 +error(0.001338700097173320998) D30 D32 D34 D43 D61 L0 +error(0.001338700097173320998) D30 D32 D34 D57 D59 D61 L0 +error(0.003340032800510209492) D30 D32 D34 L0 +error(0.0006697986788568588423) D30 D32 D38 D39 D41 D50 +error(0.0006697986788568588423) D30 D32 D38 D39 D50 D59 +error(0.001338700097173320998) D30 D32 D38 D47 D56 L0 +error(0.0006697986788568588423) D30 D32 D38 D47 D57 D59 L0 +error(0.0006697986788568588423) D30 D32 D38 D47 D57 L0 +error(0.0006697986788568588423) D30 D32 D39 D41 D50 D61 +error(0.0006697986788568588423) D30 D32 D39 D50 D59 D61 +error(0.001338700097173320998) D30 D32 D41 D50 D59 +error(0.0006697986788568588423) D30 D32 D41 D52 D56 D57 L0 +error(0.0006697986788568588423) D30 D32 D41 D52 D56 D59 D61 L0 +error(0.0006697986788568588423) D30 D32 D43 D52 D57 D59 L0 +error(0.0006697986788568588423) D30 D32 D43 D52 D61 L0 +error(0.0006697986788568588423) D30 D32 D47 D56 D57 D59 L0 +error(0.0006697986788568588423) D30 D32 D47 D56 D57 L0 +error(0.001338700097173320998) D30 D32 D47 L0 +error(0.001338700097173320998) D30 D32 D50 +error(0.001338700097173320998) D30 D32 D52 D57 D59 D61 L0 +error(0.001338700097173320998) D30 D32 D52 L0 +error(0.0006697986788568588423) D30 D34 D39 D41 D43 D52 +error(0.0006697986788568588423) D30 D34 D39 D41 D52 D61 +error(0.0006697986788568588423) D30 D34 D39 D43 D52 +error(0.001338700097173320998) D30 D34 D39 D43 L0 +error(0.0006697986788568588423) D30 D34 D39 D52 D61 +error(0.0006697986788568588423) D30 D34 D39 D57 L0 +error(0.001338700097173320998) D30 D34 D39 D61 L0 +error(0.004005357180252827609) D30 D34 D43 D52 D61 +error(0.0006697986788568588423) D30 D34 D43 D57 L0 +error(0.001338700097173320998) D30 D34 D43 D61 L0 +error(0.004005357180252827609) D30 D34 D52 +error(0.001338700097173320998) D30 D34 D57 D61 L0 +error(0.002673815958446297981) D30 D34 L0 +error(0.001338700097173320998) D30 D39 D48 D56 +error(0.002673815958446297981) D30 D39 D48 D57 +error(0.001338700097173320998) D30 D39 D48 D57 D59 +error(0.0006697986788568588423) D30 D39 D48 D59 D61 +error(0.004669790293214320931) D30 D39 D48 D61 +error(0.0006697986788568588423) D30 D39 D50 D52 D57 D59 L0 +error(0.0006697986788568588423) D30 D39 D50 D52 D61 L0 +error(0.0006697986788568588423) D30 D39 D52 D57 L0 +error(0.0006697986788568588423) D30 D39 D52 D61 L0 +error(0.0006697986788568588423) D30 D41 D50 D52 D56 D57 L0 +error(0.0006697986788568588423) D30 D41 D50 D52 D56 D59 D61 L0 +error(0.0006697986788568588423) D30 D43 D52 D57 L0 +error(0.0006697986788568588423) D30 D43 D52 D61 L0 +error(0.006657753962803452177) D30 D48 +error(0.0006697986788568588423) D30 D48 D56 D57 +error(0.0006697986788568588423) D30 D48 D56 D57 D59 +error(0.001338700097173320998) D30 D48 D57 D59 D61 +error(0.001338700097173320998) D30 D48 D57 D61 +error(0.001338700097173320998) D30 D50 D52 D57 D59 D61 L0 +error(0.001338700097173320998) D30 D50 D52 L0 +error(0.001338700097173320998) D30 D52 D57 D61 L0 +error(0.001338700097173320998) D30 D52 L0 +error(0.001338700097173320998) D31 D32 D35 D40 D41 D44 L0 +error(0.001338700097173320998) D31 D32 D35 D40 D41 D62 L0 +error(0.0006697986788568588423) D31 D32 D35 D40 D58 L0 +error(0.001338700097173320998) D31 D32 D35 D40 D59 D62 L0 +error(0.0006697986788568588423) D31 D32 D35 D41 D59 L0 +error(0.0006697986788568588423) D31 D32 D35 D44 D58 D59 L0 +error(0.001338700097173320998) D31 D32 D35 D44 D62 L0 +error(0.001338700097173320998) D31 D32 D35 D58 D59 D62 L0 +error(0.003340032800510209492) D31 D32 D35 L0 +error(0.0006697986788568588423) D31 D32 D37 D38 D47 D58 L0 +error(0.0006697986788568588423) D31 D32 D37 D47 D56 D58 L0 +error(0.0006697986788568588423) D31 D32 D38 D40 D41 D50 +error(0.0006697986788568588423) D31 D32 D38 D40 D50 D59 +error(0.001338700097173320998) D31 D32 D38 D47 D56 L0 +error(0.0006697986788568588423) D31 D32 D38 D47 D58 D59 L0 +error(0.0006697986788568588423) D31 D32 D40 D41 D50 D62 +error(0.0006697986788568588423) D31 D32 D40 D50 D59 D62 +error(0.001338700097173320998) D31 D32 D41 D50 D59 +error(0.0006697986788568588423) D31 D32 D41 D53 D56 D58 L0 +error(0.0006697986788568588423) D31 D32 D41 D53 D56 D59 D62 L0 +error(0.0006697986788568588423) D31 D32 D44 D53 D58 D59 L0 +error(0.0006697986788568588423) D31 D32 D44 D53 D62 L0 +error(0.0006697986788568588423) D31 D32 D47 D56 D58 D59 L0 +error(0.001338700097173320998) D31 D32 D47 L0 +error(0.001338700097173320998) D31 D32 D50 +error(0.001338700097173320998) D31 D32 D53 D58 D59 D62 L0 +error(0.001338700097173320998) D31 D32 D53 L0 +error(0.001338700097173320998) D31 D33 D35 D40 D42 D44 L0 +error(0.001338700097173320998) D31 D33 D35 D40 D42 D62 L0 +error(0.0006697986788568588423) D31 D33 D35 D40 D58 L0 +error(0.001338700097173320998) D31 D33 D35 D40 D60 D62 L0 +error(0.0006697986788568588423) D31 D33 D35 D42 D60 L0 +error(0.0006697986788568588423) D31 D33 D35 D44 D58 D60 L0 +error(0.001338700097173320998) D31 D33 D35 D44 D62 L0 +error(0.001338700097173320998) D31 D33 D35 D58 D60 D62 L0 +error(0.003340032800510209492) D31 D33 D35 L0 +error(0.0006697986788568588423) D31 D33 D40 D42 D51 +error(0.0006697986788568588423) D31 D33 D40 D42 D51 D62 +error(0.001338700097173320998) D31 D33 D40 D42 L0 +error(0.0006697986788568588423) D31 D33 D40 D51 D60 +error(0.0006697986788568588423) D31 D33 D40 D51 D60 D62 +error(0.0006697986788568588423) D31 D33 D40 D58 L0 +error(0.001338700097173320998) D31 D33 D40 D60 L0 +error(0.001338700097173320998) D31 D33 D42 D51 D60 +error(0.0006697986788568588423) D31 D33 D42 D53 D58 L0 +error(0.0006697986788568588423) D31 D33 D42 D53 D60 D62 L0 +error(0.0006697986788568588423) D31 D33 D42 D58 L0 +error(0.001338700097173320998) D31 D33 D42 D60 L0 +error(0.0006697986788568588423) D31 D33 D44 D53 D58 D60 L0 +error(0.0006697986788568588423) D31 D33 D44 D53 D62 L0 +error(0.001338700097173320998) D31 D33 D51 +error(0.001338700097173320998) D31 D33 D53 D58 D60 D62 L0 +error(0.001338700097173320998) D31 D33 D53 L0 +error(0.001338700097173320998) D31 D33 D58 D60 L0 +error(0.002673815958446297981) D31 D33 L0 +error(0.0006697986788568588423) D31 D35 D37 D40 D49 +error(0.0006697986788568588423) D31 D35 D37 D49 D58 +error(0.0006697986788568588423) D31 D35 D40 D41 D44 D53 +error(0.0006697986788568588423) D31 D35 D40 D41 D53 D62 +error(0.0006697986788568588423) D31 D35 D40 D42 D44 D53 +error(0.0006697986788568588423) D31 D35 D40 D42 D53 D62 +error(0.001338700097173320998) D31 D35 D40 D49 D58 +error(0.0006697986788568588423) D31 D35 D40 D49 D60 +error(0.004005357180252827609) D31 D35 D44 D53 D62 +error(0.001338700097173320998) D31 D35 D49 +error(0.0006697986788568588423) D31 D35 D49 D58 D60 +error(0.004005357180252827609) D31 D35 D53 +error(0.0006697986788568588423) D31 D36 D37 D46 L0 +error(0.0006697986788568588423) D31 D36 D46 D55 L0 +error(0.004005357180252827609) D31 D37 D46 D55 L0 +error(0.0006697986788568588423) D31 D37 D46 D58 L0 +error(0.001338700097173320998) D31 D40 D49 D55 +error(0.001338700097173320998) D31 D40 D49 D55 D56 +error(0.001338700097173320998) D31 D40 D49 D55 D58 D59 +error(0.001338700097173320998) D31 D40 D49 D55 D58 D60 +error(0.004005357180252827609) D31 D40 D49 D55 D62 +error(0.002673815958446297981) D31 D40 D49 D58 +error(0.0006697986788568588423) D31 D40 D49 D59 D62 +error(0.0006697986788568588423) D31 D40 D49 D60 D62 +error(0.0006697986788568588423) D31 D40 D50 D53 D55 D58 D59 L0 +error(0.0006697986788568588423) D31 D40 D50 D53 D55 D62 L0 +error(0.0006697986788568588423) D31 D40 D51 D53 D55 D58 D60 L0 +error(0.0006697986788568588423) D31 D40 D51 D53 D55 D62 L0 +error(0.0006697986788568588423) D31 D40 D51 D55 D58 D60 L0 +error(0.0006697986788568588423) D31 D40 D51 D55 L0 +error(0.0006697986788568588423) D31 D41 D50 D53 D56 D58 L0 +error(0.0006697986788568588423) D31 D41 D50 D53 D56 D59 D62 L0 +error(0.0006697986788568588423) D31 D42 D51 D53 D58 L0 +error(0.0006697986788568588423) D31 D42 D51 D53 D60 D62 L0 +error(0.0006697986788568588423) D31 D42 D51 D58 L0 +error(0.0006697986788568588423) D31 D42 D51 D60 L0 +error(0.0006697986788568588423) D31 D46 D55 D58 L0 +error(0.004005357180252827609) D31 D46 L0 +error(0.007978628588222850399) D31 D49 +error(0.0006697986788568588423) D31 D49 D55 D56 D58 +error(0.0006697986788568588423) D31 D49 D55 D58 +error(0.0006697986788568588423) D31 D49 D56 D58 D59 +error(0.001338700097173320998) D31 D49 D58 D59 D62 +error(0.0006697986788568588423) D31 D49 D58 D60 +error(0.001338700097173320998) D31 D49 D58 D60 D62 +error(0.001338700097173320998) D31 D50 D53 D58 D59 D62 L0 +error(0.001338700097173320998) D31 D50 D53 L0 +error(0.001338700097173320998) D31 D51 D53 D58 D60 D62 L0 +error(0.001338700097173320998) D31 D51 D53 L0 +error(0.001338700097173320998) D31 D51 D58 D60 L0 +error(0.001338700097173320998) D31 D51 L0 +error(0.0006697986788568588423) D32 D34 D38 D39 D48 D59 L0 +error(0.0006697986788568588423) D32 D34 D38 D48 D57 D59 L0 +error(0.001338700097173320998) D32 D34 D39 D48 D57 L0 +error(0.0006697986788568588423) D32 D34 D39 D48 D59 D61 L0 +error(0.001338700097173320998) D32 D34 D41 D43 L0 +error(0.0006697986788568588423) D32 D34 D41 D59 L0 +error(0.001338700097173320998) D32 D34 D41 D61 L0 +error(0.0006697986788568588423) D32 D34 D43 D57 D59 L0 +error(0.0006697986788568588423) D32 D34 D43 D57 D61 L0 +error(0.0006697986788568588423) D32 D34 D43 D61 L0 +error(0.0006697986788568588423) D32 D34 D48 D57 D59 D61 L0 +error(0.001338700097173320998) D32 D34 D48 L0 +error(0.001338700097173320998) D32 D34 D59 D61 L0 +error(0.002673815958446297981) D32 D34 L0 +error(0.0006697986788568588423) D32 D35 D38 D40 D49 D59 L0 +error(0.0006697986788568588423) D32 D35 D38 D49 D58 D59 L0 +error(0.001338700097173320998) D32 D35 D40 D49 D58 L0 +error(0.0006697986788568588423) D32 D35 D40 D49 D59 D62 L0 +error(0.001338700097173320998) D32 D35 D41 D44 L0 +error(0.0006697986788568588423) D32 D35 D41 D59 L0 +error(0.001338700097173320998) D32 D35 D41 D62 L0 +error(0.0006697986788568588423) D32 D35 D44 D58 D59 L0 +error(0.0006697986788568588423) D32 D35 D44 D58 D62 L0 +error(0.0006697986788568588423) D32 D35 D44 D62 L0 +error(0.0006697986788568588423) D32 D35 D49 D58 D59 D62 L0 +error(0.001338700097173320998) D32 D35 D49 L0 +error(0.001338700097173320998) D32 D35 D59 D62 L0 +error(0.002673815958446297981) D32 D35 L0 +error(0.0006697986788568588423) D32 D39 D41 D43 D52 L0 +error(0.0006697986788568588423) D32 D39 D41 D52 D61 L0 +error(0.0006697986788568588423) D32 D40 D41 D44 D53 L0 +error(0.0006697986788568588423) D32 D40 D41 D53 D62 L0 +error(0.0006697986788568588423) D32 D41 D43 D52 L0 +error(0.0006697986788568588423) D32 D41 D44 D53 L0 +error(0.004005357180252827609) D32 D41 D50 D56 +error(0.001338700097173320998) D32 D41 D50 D56 D57 +error(0.001338700097173320998) D32 D41 D50 D56 D58 +error(0.001338700097173320998) D32 D41 D50 D56 D59 D61 +error(0.001338700097173320998) D32 D41 D50 D56 D59 D62 +error(0.002673815958446297981) D32 D41 D50 D59 +error(0.0006697986788568588423) D32 D41 D50 D61 +error(0.0006697986788568588423) D32 D41 D50 D62 +error(0.0006697986788568588423) D32 D41 D52 D56 D59 D61 L0 +error(0.0006697986788568588423) D32 D41 D52 D56 L0 +error(0.0006697986788568588423) D32 D41 D52 D61 L0 +error(0.0006697986788568588423) D32 D41 D53 D56 D59 D62 L0 +error(0.0006697986788568588423) D32 D41 D53 D56 L0 +error(0.0006697986788568588423) D32 D41 D53 D62 L0 +error(0.0006697986788568588423) D32 D43 D52 D57 D59 L0 +error(0.0006697986788568588423) D32 D43 D52 D57 D61 L0 +error(0.001338700097173320998) D32 D43 D52 D61 L0 +error(0.0006697986788568588423) D32 D44 D53 D58 D59 L0 +error(0.0006697986788568588423) D32 D44 D53 D58 D62 L0 +error(0.001338700097173320998) D32 D44 D53 D62 L0 +error(0.007978628588222850399) D32 D50 +error(0.0006697986788568588423) D32 D50 D56 D57 D59 +error(0.0006697986788568588423) D32 D50 D56 D58 D59 +error(0.0006697986788568588423) D32 D50 D57 D59 D61 +error(0.0006697986788568588423) D32 D50 D58 D59 D62 +error(0.001338700097173320998) D32 D50 D59 D61 +error(0.001338700097173320998) D32 D50 D59 D62 +error(0.001338700097173320998) D32 D52 D59 D61 L0 +error(0.002673815958446297981) D32 D52 L0 +error(0.001338700097173320998) D32 D53 D59 D62 L0 +error(0.002673815958446297981) D32 D53 L0 +error(0.001338700097173320998) D33 D35 D40 D49 D58 L0 +error(0.0006697986788568588423) D33 D35 D40 D49 D60 D62 L0 +error(0.0006697986788568588423) D33 D35 D40 D49 D60 L0 +error(0.001338700097173320998) D33 D35 D42 D44 L0 +error(0.0006697986788568588423) D33 D35 D42 D60 L0 +error(0.001338700097173320998) D33 D35 D42 D62 L0 +error(0.0006697986788568588423) D33 D35 D44 D58 D60 L0 +error(0.0006697986788568588423) D33 D35 D44 D58 D62 L0 +error(0.0006697986788568588423) D33 D35 D44 D62 L0 +error(0.0006697986788568588423) D33 D35 D49 D58 D60 D62 L0 +error(0.0006697986788568588423) D33 D35 D49 D58 D60 L0 +error(0.001338700097173320998) D33 D35 D49 L0 +error(0.001338700097173320998) D33 D35 D60 D62 L0 +error(0.002673815958446297981) D33 D35 L0 +error(0.0006697986788568588423) D33 D40 D42 D44 D53 L0 +error(0.0006697986788568588423) D33 D40 D42 D53 D62 L0 +error(0.0006697986788568588423) D33 D42 D44 D53 L0 +error(0.004669790293214320931) D33 D42 D51 +error(0.001338700097173320998) D33 D42 D51 D58 +error(0.002673815958446297981) D33 D42 D51 D60 +error(0.001338700097173320998) D33 D42 D51 D60 D62 +error(0.0006697986788568588423) D33 D42 D51 D62 +error(0.0006697986788568588423) D33 D42 D53 D60 D62 L0 +error(0.0006697986788568588423) D33 D42 D53 D62 L0 +error(0.0006697986788568588423) D33 D42 D53 L0 +error(0.001338700097173320998) D33 D42 D60 L0 +error(0.002673815958446297981) D33 D42 L0 +error(0.0006697986788568588423) D33 D44 D53 D58 D60 L0 +error(0.0006697986788568588423) D33 D44 D53 D58 D62 L0 +error(0.001338700097173320998) D33 D44 D53 D62 L0 +error(0.006657753962803452177) D33 D51 +error(0.0006697986788568588423) D33 D51 D58 D60 +error(0.0006697986788568588423) D33 D51 D58 D60 D62 +error(0.001338700097173320998) D33 D51 D60 +error(0.001338700097173320998) D33 D51 D60 D62 +error(0.001338700097173320998) D33 D53 D60 D62 L0 +error(0.002673815958446297981) D33 D53 L0 +error(0.001338700097173320998) D33 D60 L0 +error(0.005995987492949031786) D33 L0 +error(0.0006697986788568588423) D34 D38 D39 D48 L0 +error(0.0006697986788568588423) D34 D38 D48 D57 L0 +error(0.0006697986788568588423) D34 D39 D41 D50 D61 L0 +error(0.004005357180252827609) D34 D39 D48 D57 L0 +error(0.0006697986788568588423) D34 D39 D48 D61 L0 +error(0.0006697986788568588423) D34 D39 D50 D59 D61 L0 +error(0.0006697986788568588423) D34 D41 D43 D52 +error(0.001338700097173320998) D34 D41 D50 D59 L0 +error(0.0006697986788568588423) D34 D41 D50 D61 L0 +error(0.0006697986788568588423) D34 D41 D52 D61 +error(0.0006697986788568588423) D34 D43 D52 +error(0.001338700097173320998) D34 D43 D52 D57 +error(0.001338700097173320998) D34 D43 D52 D57 D59 +error(0.004005357180252827609) D34 D43 D52 D57 D61 +error(0.002673815958446297981) D34 D43 D52 D61 +error(0.0006697986788568588423) D34 D43 D57 D61 L0 +error(0.0006697986788568588423) D34 D43 D57 L0 +error(0.0006697986788568588423) D34 D43 D61 L0 +error(0.002006705456917235505) D34 D43 L0 +error(0.0006697986788568588423) D34 D48 D57 D61 L0 +error(0.004005357180252827609) D34 D48 L0 +error(0.0006697986788568588423) D34 D50 D59 D61 L0 +error(0.001338700097173320998) D34 D50 L0 +error(0.006657753962803452177) D34 D52 +error(0.0006697986788568588423) D34 D52 D57 D59 D61 +error(0.0006697986788568588423) D34 D52 D57 D61 +error(0.0006697986788568588423) D34 D52 D59 D61 +error(0.001338700097173320998) D34 D52 D61 +error(0.001338700097173320998) D34 D61 L0 +error(0.003340032800510209492) D34 L0 +error(0.0006697986788568588423) D35 D40 D41 D50 D62 L0 +error(0.0006697986788568588423) D35 D40 D42 D51 D62 L0 +error(0.0006697986788568588423) D35 D40 D50 D59 D62 L0 +error(0.0006697986788568588423) D35 D40 D51 D60 D62 L0 +error(0.0006697986788568588423) D35 D41 D44 D53 +error(0.001338700097173320998) D35 D41 D50 D59 L0 +error(0.0006697986788568588423) D35 D41 D50 D62 L0 +error(0.0006697986788568588423) D35 D41 D53 D62 +error(0.0006697986788568588423) D35 D42 D44 D53 +error(0.001338700097173320998) D35 D42 D51 D60 L0 +error(0.0006697986788568588423) D35 D42 D51 D62 L0 +error(0.0006697986788568588423) D35 D42 D53 D62 +error(0.001338700097173320998) D35 D44 D53 D58 D59 +error(0.001338700097173320998) D35 D44 D53 D58 D60 +error(0.004005357180252827609) D35 D44 D53 D58 D62 +error(0.002673815958446297981) D35 D44 D53 D62 +error(0.0006697986788568588423) D35 D50 D59 D62 L0 +error(0.001338700097173320998) D35 D50 L0 +error(0.0006697986788568588423) D35 D51 D60 D62 L0 +error(0.001338700097173320998) D35 D51 L0 +error(0.006657753962803452177) D35 D53 +error(0.0006697986788568588423) D35 D53 D58 D59 D62 +error(0.0006697986788568588423) D35 D53 D58 D60 D62 +error(0.0006697986788568588423) D35 D53 D59 D62 +error(0.0006697986788568588423) D35 D53 D60 D62 +error(0.003340032800510209492) D36 +error(0.002673815958446297981) D36 D37 +error(0.003340032800510209492) D36 D37 D38 +error(0.001338700097173320998) D36 D37 D56 +error(0.002673815958446297981) D36 D38 +error(0.0006697986788568588423) D36 D45 D46 D47 D54 D55 L0 +error(0.0006697986788568588423) D36 D45 D46 D47 D56 L0 +error(0.0006697986788568588423) D36 D45 D46 D54 D55 L0 +error(0.0006697986788568588423) D36 D45 D46 L0 +error(0.0006697986788568588423) D36 D45 D47 D54 L0 +error(0.0006697986788568588423) D36 D45 D47 D56 L0 +error(0.0006697986788568588423) D36 D45 D54 L0 +error(0.0006697986788568588423) D36 D45 L0 +error(0.006657753962803452177) D36 D54 +error(0.001338700097173320998) D36 D54 D55 +error(0.001338700097173320998) D36 D55 +error(0.001338700097173320998) D36 D55 D56 +error(0.005333333333333313206) D36 D56 +error(0.003340032800510209492) D37 D38 D40 +error(0.001338700097173320998) D37 D38 D58 +error(0.002673815958446297981) D37 D40 +error(0.0006697986788568588423) D37 D46 D47 D49 D55 D56 L0 +error(0.0006697986788568588423) D37 D46 D47 D49 D58 L0 +error(0.0006697986788568588423) D37 D46 D49 D55 L0 +error(0.0006697986788568588423) D37 D46 D49 D58 L0 +error(0.001338700097173320998) D37 D54 +error(0.006657753962803452177) D37 D55 +error(0.001338700097173320998) D37 D55 D56 +error(0.001338700097173320998) D37 D56 D58 +error(0.005333333333333313206) D37 D58 +error(0.002673815958446297981) D38 D39 +error(0.003340032800510209492) D38 D39 D41 +error(0.001338700097173320998) D38 D39 D59 +error(0.003340032800510209492) D38 D40 D41 +error(0.001338700097173320998) D38 D40 D59 +error(0.0006697986788568588423) D38 D47 D48 D50 D54 D56 D57 L0 +error(0.0006697986788568588423) D38 D47 D48 D50 D54 D59 L0 +error(0.0006697986788568588423) D38 D47 D48 D54 D56 D57 L0 +error(0.0006697986788568588423) D38 D47 D48 D54 L0 +error(0.0006697986788568588423) D38 D47 D49 D50 D54 D56 D58 L0 +error(0.0006697986788568588423) D38 D47 D49 D50 D54 D59 L0 +error(0.001338700097173320998) D38 D54 +error(0.001338700097173320998) D38 D54 D55 +error(0.001338700097173320998) D38 D54 D56 D57 +error(0.001338700097173320998) D38 D54 D56 D58 +error(0.004005357180252827609) D38 D54 D59 +error(0.007978628588222850399) D38 D56 +error(0.001338700097173320998) D38 D57 +error(0.001338700097173320998) D38 D57 D59 +error(0.001338700097173320998) D38 D58 D59 +error(0.003340032800510209492) D39 D41 D43 +error(0.001338700097173320998) D39 D41 D61 +error(0.002673815958446297981) D39 D43 +error(0.0006697986788568588423) D39 D43 D52 L0 +error(0.0006697986788568588423) D39 D48 D50 D52 D57 D59 L0 +error(0.0006697986788568588423) D39 D48 D50 D52 D61 L0 +error(0.0006697986788568588423) D39 D48 D52 D57 L0 +error(0.0006697986788568588423) D39 D48 D52 D61 L0 +error(0.0006697986788568588423) D39 D52 D61 L0 +error(0.001338700097173320998) D39 D56 +error(0.006657753962803452177) D39 D57 +error(0.001338700097173320998) D39 D57 D59 +error(0.001338700097173320998) D39 D59 D61 +error(0.005333333333333313206) D39 D61 +error(0.003340032800510209492) D40 D41 D44 +error(0.001338700097173320998) D40 D41 D62 +error(0.002673815958446297981) D40 D42 +error(0.003340032800510209492) D40 D42 D44 +error(0.0006697986788568588423) D40 D42 D51 L0 +error(0.001338700097173320998) D40 D42 D62 +error(0.0006697986788568588423) D40 D49 D50 D53 D55 D58 D59 L0 +error(0.0006697986788568588423) D40 D49 D50 D53 D55 D62 L0 +error(0.0006697986788568588423) D40 D49 D51 D53 D55 D58 D60 L0 +error(0.0006697986788568588423) D40 D49 D51 D53 D55 D62 L0 +error(0.0006697986788568588423) D40 D49 D51 D55 D58 D60 L0 +error(0.0006697986788568588423) D40 D49 D51 D55 L0 +error(0.0006697986788568588423) D40 D51 D60 L0 +error(0.001338700097173320998) D40 D55 +error(0.001338700097173320998) D40 D55 D56 +error(0.001338700097173320998) D40 D55 D58 D59 +error(0.001338700097173320998) D40 D55 D58 D60 +error(0.004005357180252827609) D40 D55 D62 +error(0.007978628588222850399) D40 D58 +error(0.001338700097173320998) D40 D59 D62 +error(0.001338700097173320998) D40 D60 +error(0.001338700097173320998) D40 D60 D62 +error(0.002673815958446297981) D41 D43 +error(0.002673815958446297981) D41 D44 +error(0.0006697986788568588423) D41 D50 D52 D56 D59 D61 L0 +error(0.0006697986788568588423) D41 D50 D52 D56 L0 +error(0.0006697986788568588423) D41 D50 D53 D56 D59 D62 L0 +error(0.0006697986788568588423) D41 D50 D53 D56 L0 +error(0.004005357180252827609) D41 D56 +error(0.001338700097173320998) D41 D56 D57 +error(0.001338700097173320998) D41 D56 D58 +error(0.001338700097173320998) D41 D56 D59 D61 +error(0.001338700097173320998) D41 D56 D59 D62 +error(0.007978628588222850399) D41 D59 +error(0.001338700097173320998) D41 D61 +error(0.001338700097173320998) D41 D62 +error(0.005995987492949031786) D42 +error(0.002673815958446297981) D42 D44 +error(0.0006697986788568588423) D42 D51 D53 D60 D62 L0 +error(0.0006697986788568588423) D42 D51 D53 L0 +error(0.004669790293214320931) D42 D51 D60 L0 +error(0.001338700097173320998) D42 D51 L0 +error(0.001338700097173320998) D42 D58 +error(0.006657753962803452177) D42 D60 +error(0.001338700097173320998) D42 D60 D62 +error(0.001338700097173320998) D42 D62 +error(0.002006705456917235505) D43 +error(0.0006697986788568588423) D43 D52 D57 D61 L0 +error(0.0006697986788568588423) D43 D52 D57 L0 +error(0.001338700097173320998) D43 D52 D61 L0 +error(0.0006697986788568588423) D43 D52 L0 +error(0.001338700097173320998) D43 D57 +error(0.001338700097173320998) D43 D57 D59 +error(0.004005357180252827609) D43 D57 D61 +error(0.006657753962803452177) D43 D61 +error(0.001338700097173320998) D44 D58 D59 +error(0.001338700097173320998) D44 D58 D60 +error(0.004005357180252827609) D44 D58 D62 +error(0.006657753962803452177) D44 D62 +error(0.001338700097173320998) D45 D46 D47 D54 D55 D56 L0 +error(0.001338700097173320998) D45 D46 D47 D54 D55 D74 L0 +error(0.0006697986788568588423) D45 D46 D47 D54 D72 L0 +error(0.001338700097173320998) D45 D46 D47 D54 D73 D74 L0 +error(0.0006697986788568588423) D45 D46 D47 D55 D73 L0 +error(0.0006697986788568588423) D45 D46 D47 D56 D72 D73 L0 +error(0.001338700097173320998) D45 D46 D47 D56 D74 L0 +error(0.001338700097173320998) D45 D46 D47 D72 D73 D74 L0 +error(0.003340032800510209492) D45 D46 D47 L0 +error(0.0006697986788568588423) D45 D46 D49 D54 D55 D64 +error(0.0006697986788568588423) D45 D46 D49 D54 D55 D64 D74 +error(0.0006697986788568588423) D45 D46 D49 D54 D64 D73 +error(0.0006697986788568588423) D45 D46 D49 D54 D64 D73 D74 +error(0.001338700097173320998) D45 D46 D49 D55 D64 D73 +error(0.001338700097173320998) D45 D46 D49 D64 +error(0.001338700097173320998) D45 D46 D54 D55 L0 +error(0.0006697986788568588423) D45 D46 D54 D72 L0 +error(0.001338700097173320998) D45 D46 D54 D73 L0 +error(0.0006697986788568588423) D45 D46 D55 D65 D72 L0 +error(0.0006697986788568588423) D45 D46 D55 D65 D73 D74 L0 +error(0.0006697986788568588423) D45 D46 D55 D72 L0 +error(0.001338700097173320998) D45 D46 D55 D73 L0 +error(0.0006697986788568588423) D45 D46 D56 D65 D72 D73 L0 +error(0.0006697986788568588423) D45 D46 D56 D65 D74 L0 +error(0.001338700097173320998) D45 D46 D65 D72 D73 D74 L0 +error(0.001338700097173320998) D45 D46 D65 L0 +error(0.001338700097173320998) D45 D46 D72 D73 L0 +error(0.002673815958446297981) D45 D46 L0 +error(0.001338700097173320998) D45 D47 D54 D56 L0 +error(0.0006697986788568588423) D45 D47 D54 D63 +error(0.001338700097173320998) D45 D47 D54 D63 D72 +error(0.0006697986788568588423) D45 D47 D54 D63 D73 +error(0.0006697986788568588423) D45 D47 D54 D72 L0 +error(0.001338700097173320998) D45 D47 D54 D74 L0 +error(0.0006697986788568588423) D45 D47 D56 D72 L0 +error(0.001338700097173320998) D45 D47 D56 D74 L0 +error(0.001338700097173320998) D45 D47 D63 +error(0.0006697986788568588423) D45 D47 D63 D72 +error(0.0006697986788568588423) D45 D47 D63 D72 D73 +error(0.001338700097173320998) D45 D47 D72 D74 L0 +error(0.002673815958446297981) D45 D47 L0 +error(0.0006697986788568588423) D45 D50 D54 D55 D56 D65 L0 +error(0.0006697986788568588423) D45 D50 D54 D55 D65 D74 L0 +error(0.0006697986788568588423) D45 D50 D54 D56 D65 L0 +error(0.0006697986788568588423) D45 D50 D54 D65 D74 L0 +error(0.004005357180252827609) D45 D50 D56 D65 D74 L0 +error(0.004005357180252827609) D45 D50 D65 L0 +error(0.001338700097173320998) D45 D54 D63 +error(0.002673815958446297981) D45 D54 D63 D72 +error(0.001338700097173320998) D45 D54 D63 D72 D73 +error(0.0006697986788568588423) D45 D54 D63 D73 D74 +error(0.004669790293214320931) D45 D54 D63 D74 +error(0.0006697986788568588423) D45 D54 D64 D65 D72 D73 L0 +error(0.0006697986788568588423) D45 D54 D64 D65 D74 L0 +error(0.0006697986788568588423) D45 D54 D64 D72 D73 L0 +error(0.0006697986788568588423) D45 D54 D64 L0 +error(0.0006697986788568588423) D45 D54 D65 D72 L0 +error(0.0006697986788568588423) D45 D54 D65 D74 L0 +error(0.001338700097173320998) D45 D54 D72 L0 +error(0.002006705456917235505) D45 D54 L0 +error(0.0006697986788568588423) D45 D55 D64 D65 D72 L0 +error(0.0006697986788568588423) D45 D55 D64 D65 D73 D74 L0 +error(0.0006697986788568588423) D45 D55 D64 D72 L0 +error(0.0006697986788568588423) D45 D55 D64 D73 L0 +error(0.0006697986788568588423) D45 D56 D65 D72 L0 +error(0.0006697986788568588423) D45 D56 D65 D74 L0 +error(0.006657753962803452177) D45 D63 +error(0.0006697986788568588423) D45 D63 D72 +error(0.0006697986788568588423) D45 D63 D72 D73 +error(0.001338700097173320998) D45 D63 D72 D73 D74 +error(0.001338700097173320998) D45 D63 D72 D74 +error(0.001338700097173320998) D45 D64 D65 D72 D73 D74 L0 +error(0.001338700097173320998) D45 D64 D65 L0 +error(0.001338700097173320998) D45 D64 D72 D73 L0 +error(0.001338700097173320998) D45 D64 L0 +error(0.001338700097173320998) D45 D65 D72 D74 L0 +error(0.001338700097173320998) D45 D65 L0 +error(0.001338700097173320998) D45 D72 L0 +error(0.002006705456917235505) D45 L0 +error(0.001338700097173320998) D46 D47 D49 D55 D56 D58 L0 +error(0.001338700097173320998) D46 D47 D49 D55 D56 D76 L0 +error(0.0006697986788568588423) D46 D47 D49 D55 D73 L0 +error(0.001338700097173320998) D46 D47 D49 D55 D74 D76 L0 +error(0.0006697986788568588423) D46 D47 D49 D56 D74 L0 +error(0.0006697986788568588423) D46 D47 D49 D58 D73 D74 L0 +error(0.001338700097173320998) D46 D47 D49 D58 D76 L0 +error(0.001338700097173320998) D46 D47 D49 D73 D74 D76 L0 +error(0.003340032800510209492) D46 D47 D49 L0 +error(0.0006697986788568588423) D46 D47 D50 D54 D55 D56 D65 +error(0.0006697986788568588423) D46 D47 D50 D54 D55 D65 D74 +error(0.0006697986788568588423) D46 D47 D50 D55 D56 D65 D76 +error(0.0006697986788568588423) D46 D47 D50 D55 D65 D74 D76 +error(0.001338700097173320998) D46 D47 D50 D56 D65 D74 +error(0.001338700097173320998) D46 D47 D50 D65 +error(0.001338700097173320998) D46 D47 D54 D63 D72 L0 +error(0.0006697986788568588423) D46 D47 D54 D63 D73 D74 L0 +error(0.0006697986788568588423) D46 D47 D54 D63 D73 L0 +error(0.0006697986788568588423) D46 D47 D56 D67 D72 D73 L0 +error(0.0006697986788568588423) D46 D47 D56 D67 D72 D74 D76 L0 +error(0.0006697986788568588423) D46 D47 D58 D67 D73 D74 L0 +error(0.0006697986788568588423) D46 D47 D58 D67 D76 L0 +error(0.0006697986788568588423) D46 D47 D63 D72 D73 D74 L0 +error(0.0006697986788568588423) D46 D47 D63 D72 D73 L0 +error(0.001338700097173320998) D46 D47 D63 L0 +error(0.001338700097173320998) D46 D47 D67 D73 D74 D76 L0 +error(0.001338700097173320998) D46 D47 D67 L0 +error(0.001338700097173320998) D46 D49 D55 D58 L0 +error(0.0006697986788568588423) D46 D49 D55 D73 L0 +error(0.001338700097173320998) D46 D49 D55 D76 L0 +error(0.0006697986788568588423) D46 D49 D58 D73 L0 +error(0.001338700097173320998) D46 D49 D58 D76 L0 +error(0.001338700097173320998) D46 D49 D73 D76 L0 +error(0.002673815958446297981) D46 D49 L0 +error(0.0006697986788568588423) D46 D53 D55 D56 D58 D67 L0 +error(0.0006697986788568588423) D46 D53 D55 D56 D67 D76 L0 +error(0.0006697986788568588423) D46 D53 D55 D58 D67 L0 +error(0.0006697986788568588423) D46 D53 D55 D67 D76 L0 +error(0.004005357180252827609) D46 D53 D58 D67 D76 L0 +error(0.004005357180252827609) D46 D53 D67 L0 +error(0.001338700097173320998) D46 D55 D64 D72 +error(0.002673815958446297981) D46 D55 D64 D73 +error(0.001338700097173320998) D46 D55 D64 D73 D74 +error(0.0006697986788568588423) D46 D55 D64 D74 D76 +error(0.004669790293214320931) D46 D55 D64 D76 +error(0.0006697986788568588423) D46 D55 D65 D67 D73 D74 L0 +error(0.0006697986788568588423) D46 D55 D65 D67 D76 L0 +error(0.0006697986788568588423) D46 D55 D67 D73 L0 +error(0.0006697986788568588423) D46 D55 D67 D76 L0 +error(0.0006697986788568588423) D46 D56 D65 D67 D72 D73 L0 +error(0.0006697986788568588423) D46 D56 D65 D67 D72 D74 D76 L0 +error(0.0006697986788568588423) D46 D58 D67 D73 L0 +error(0.0006697986788568588423) D46 D58 D67 D76 L0 +error(0.006657753962803452177) D46 D64 +error(0.0006697986788568588423) D46 D64 D72 D73 +error(0.0006697986788568588423) D46 D64 D72 D73 D74 +error(0.001338700097173320998) D46 D64 D73 D74 D76 +error(0.001338700097173320998) D46 D64 D73 D76 +error(0.001338700097173320998) D46 D65 D67 D73 D74 D76 L0 +error(0.001338700097173320998) D46 D65 D67 L0 +error(0.001338700097173320998) D46 D67 D73 D76 L0 +error(0.001338700097173320998) D46 D67 L0 +error(0.001338700097173320998) D47 D48 D50 D56 D57 D59 L0 +error(0.001338700097173320998) D47 D48 D50 D56 D57 D77 L0 +error(0.0006697986788568588423) D47 D48 D50 D56 D74 L0 +error(0.001338700097173320998) D47 D48 D50 D56 D75 D77 L0 +error(0.0006697986788568588423) D47 D48 D50 D57 D75 L0 +error(0.0006697986788568588423) D47 D48 D50 D59 D74 D75 L0 +error(0.001338700097173320998) D47 D48 D50 D59 D77 L0 +error(0.001338700097173320998) D47 D48 D50 D74 D75 D77 L0 +error(0.003340032800510209492) D47 D48 D50 L0 +error(0.0006697986788568588423) D47 D48 D52 D56 D57 D66 +error(0.0006697986788568588423) D47 D48 D52 D56 D57 D66 D77 +error(0.0006697986788568588423) D47 D48 D52 D56 D66 D75 +error(0.0006697986788568588423) D47 D48 D52 D56 D66 D75 D77 +error(0.001338700097173320998) D47 D48 D52 D57 D66 D75 +error(0.001338700097173320998) D47 D48 D52 D66 +error(0.001338700097173320998) D47 D48 D56 D57 L0 +error(0.0006697986788568588423) D47 D48 D56 D74 L0 +error(0.001338700097173320998) D47 D48 D56 D75 L0 +error(0.0006697986788568588423) D47 D48 D57 D68 D74 L0 +error(0.0006697986788568588423) D47 D48 D57 D68 D75 D77 L0 +error(0.0006697986788568588423) D47 D48 D57 D74 L0 +error(0.001338700097173320998) D47 D48 D57 D75 L0 +error(0.0006697986788568588423) D47 D48 D59 D68 D74 D75 L0 +error(0.0006697986788568588423) D47 D48 D59 D68 D77 L0 +error(0.001338700097173320998) D47 D48 D68 D74 D75 D77 L0 +error(0.001338700097173320998) D47 D48 D68 L0 +error(0.001338700097173320998) D47 D48 D74 D75 L0 +error(0.002673815958446297981) D47 D48 L0 +error(0.001338700097173320998) D47 D49 D50 D56 D58 D59 L0 +error(0.001338700097173320998) D47 D49 D50 D56 D58 D77 L0 +error(0.0006697986788568588423) D47 D49 D50 D56 D74 L0 +error(0.001338700097173320998) D47 D49 D50 D56 D76 D77 L0 +error(0.0006697986788568588423) D47 D49 D50 D58 D76 L0 +error(0.0006697986788568588423) D47 D49 D50 D59 D74 D76 L0 +error(0.001338700097173320998) D47 D49 D50 D59 D77 L0 +error(0.001338700097173320998) D47 D49 D50 D74 D76 D77 L0 +error(0.003340032800510209492) D47 D49 D50 L0 +error(0.0006697986788568588423) D47 D49 D53 D55 D56 D58 D67 +error(0.0006697986788568588423) D47 D49 D53 D55 D56 D67 D76 +error(0.0006697986788568588423) D47 D49 D53 D56 D58 D67 D77 +error(0.0006697986788568588423) D47 D49 D53 D56 D67 D76 D77 +error(0.001338700097173320998) D47 D49 D53 D58 D67 D76 +error(0.001338700097173320998) D47 D49 D53 D67 +error(0.0006697986788568588423) D47 D49 D54 D55 D64 D74 L0 +error(0.0006697986788568588423) D47 D49 D54 D64 D73 D74 L0 +error(0.001338700097173320998) D47 D49 D55 D64 D73 L0 +error(0.0006697986788568588423) D47 D49 D55 D64 D74 D76 L0 +error(0.0006697986788568588423) D47 D49 D58 D68 D73 D74 L0 +error(0.0006697986788568588423) D47 D49 D58 D68 D73 D76 D77 L0 +error(0.0006697986788568588423) D47 D49 D59 D68 D74 D76 L0 +error(0.0006697986788568588423) D47 D49 D59 D68 D77 L0 +error(0.0006697986788568588423) D47 D49 D64 D73 D74 D76 L0 +error(0.001338700097173320998) D47 D49 D64 L0 +error(0.001338700097173320998) D47 D49 D68 D74 D76 D77 L0 +error(0.001338700097173320998) D47 D49 D68 L0 +error(0.0006697986788568588423) D47 D50 D54 D56 D65 +error(0.0006697986788568588423) D47 D50 D54 D65 D74 +error(0.001338700097173320998) D47 D50 D56 D65 D74 +error(0.0006697986788568588423) D47 D50 D56 D65 D75 +error(0.001338700097173320998) D47 D50 D65 +error(0.0006697986788568588423) D47 D50 D65 D74 D75 +error(0.004005357180252827609) D47 D54 D63 D72 L0 +error(0.0006697986788568588423) D47 D54 D63 D74 L0 +error(0.0006697986788568588423) D47 D54 D63 L0 +error(0.0006697986788568588423) D47 D56 D57 D59 D68 L0 +error(0.0006697986788568588423) D47 D56 D57 D68 D77 L0 +error(0.0006697986788568588423) D47 D56 D58 D59 D68 L0 +error(0.0006697986788568588423) D47 D56 D58 D68 D77 L0 +error(0.001338700097173320998) D47 D56 D65 D72 +error(0.001338700097173320998) D47 D56 D65 D72 D73 +error(0.001338700097173320998) D47 D56 D65 D72 D74 D75 +error(0.001338700097173320998) D47 D56 D65 D72 D74 D76 +error(0.004005357180252827609) D47 D56 D65 D72 D77 +error(0.002673815958446297981) D47 D56 D65 D74 +error(0.0006697986788568588423) D47 D56 D65 D75 D77 +error(0.0006697986788568588423) D47 D56 D65 D76 D77 +error(0.0006697986788568588423) D47 D56 D66 D68 D72 D74 D75 L0 +error(0.0006697986788568588423) D47 D56 D66 D68 D72 D77 L0 +error(0.0006697986788568588423) D47 D56 D66 D72 D74 D75 L0 +error(0.0006697986788568588423) D47 D56 D66 D72 L0 +error(0.0006697986788568588423) D47 D56 D67 D68 D72 D74 D76 L0 +error(0.0006697986788568588423) D47 D56 D67 D68 D72 D77 L0 +error(0.0006697986788568588423) D47 D57 D66 D68 D74 L0 +error(0.0006697986788568588423) D47 D57 D66 D68 D75 D77 L0 +error(0.0006697986788568588423) D47 D57 D66 D74 L0 +error(0.0006697986788568588423) D47 D57 D66 D75 L0 +error(0.0006697986788568588423) D47 D58 D67 D68 D73 D74 L0 +error(0.0006697986788568588423) D47 D58 D67 D68 D73 D76 D77 L0 +error(0.004005357180252827609) D47 D59 D68 D77 L0 +error(0.0006697986788568588423) D47 D63 D72 D74 L0 +error(0.0006697986788568588423) D47 D63 D72 L0 +error(0.004005357180252827609) D47 D63 L0 +error(0.007978628588222850399) D47 D65 +error(0.0006697986788568588423) D47 D65 D72 D73 D74 +error(0.0006697986788568588423) D47 D65 D72 D74 +error(0.0006697986788568588423) D47 D65 D73 D74 D76 +error(0.0006697986788568588423) D47 D65 D74 D75 +error(0.001338700097173320998) D47 D65 D74 D75 D77 +error(0.001338700097173320998) D47 D65 D74 D76 D77 +error(0.001338700097173320998) D47 D66 D68 D74 D75 D77 L0 +error(0.001338700097173320998) D47 D66 D68 L0 +error(0.001338700097173320998) D47 D66 D74 D75 L0 +error(0.001338700097173320998) D47 D66 L0 +error(0.001338700097173320998) D47 D67 D68 D74 D76 D77 L0 +error(0.001338700097173320998) D47 D67 D68 L0 +error(0.004005357180252827609) D47 D68 L0 +error(0.001338700097173320998) D48 D50 D52 D57 D59 D61 L0 +error(0.001338700097173320998) D48 D50 D52 D57 D59 D79 L0 +error(0.0006697986788568588423) D48 D50 D52 D57 D75 L0 +error(0.001338700097173320998) D48 D50 D52 D57 D77 D79 L0 +error(0.0006697986788568588423) D48 D50 D52 D59 D77 L0 +error(0.0006697986788568588423) D48 D50 D52 D61 D75 D77 L0 +error(0.001338700097173320998) D48 D50 D52 D61 D79 L0 +error(0.001338700097173320998) D48 D50 D52 D75 D77 D79 L0 +error(0.003340032800510209492) D48 D50 D52 L0 +error(0.0006697986788568588423) D48 D50 D56 D57 D59 D68 +error(0.0006697986788568588423) D48 D50 D56 D57 D68 D77 +error(0.001338700097173320998) D48 D50 D56 D65 D74 L0 +error(0.0006697986788568588423) D48 D50 D56 D65 D75 D77 L0 +error(0.0006697986788568588423) D48 D50 D56 D65 D75 L0 +error(0.0006697986788568588423) D48 D50 D57 D59 D68 D79 +error(0.0006697986788568588423) D48 D50 D57 D68 D77 D79 +error(0.001338700097173320998) D48 D50 D59 D68 D77 +error(0.0006697986788568588423) D48 D50 D59 D70 D74 D75 L0 +error(0.0006697986788568588423) D48 D50 D59 D70 D74 D77 D79 L0 +error(0.0006697986788568588423) D48 D50 D61 D70 D75 D77 L0 +error(0.0006697986788568588423) D48 D50 D61 D70 D79 L0 +error(0.0006697986788568588423) D48 D50 D65 D74 D75 D77 L0 +error(0.0006697986788568588423) D48 D50 D65 D74 D75 L0 +error(0.001338700097173320998) D48 D50 D65 L0 +error(0.001338700097173320998) D48 D50 D68 +error(0.001338700097173320998) D48 D50 D70 D75 D77 D79 L0 +error(0.001338700097173320998) D48 D50 D70 L0 +error(0.0006697986788568588423) D48 D52 D57 D59 D61 D70 +error(0.0006697986788568588423) D48 D52 D57 D59 D70 D79 +error(0.0006697986788568588423) D48 D52 D57 D61 D70 +error(0.001338700097173320998) D48 D52 D57 D61 L0 +error(0.0006697986788568588423) D48 D52 D57 D70 D79 +error(0.0006697986788568588423) D48 D52 D57 D75 L0 +error(0.001338700097173320998) D48 D52 D57 D79 L0 +error(0.004005357180252827609) D48 D52 D61 D70 D79 +error(0.0006697986788568588423) D48 D52 D61 D75 L0 +error(0.001338700097173320998) D48 D52 D61 D79 L0 +error(0.004005357180252827609) D48 D52 D70 +error(0.001338700097173320998) D48 D52 D75 D79 L0 +error(0.002673815958446297981) D48 D52 L0 +error(0.001338700097173320998) D48 D57 D66 D74 +error(0.002673815958446297981) D48 D57 D66 D75 +error(0.001338700097173320998) D48 D57 D66 D75 D77 +error(0.0006697986788568588423) D48 D57 D66 D77 D79 +error(0.004669790293214320931) D48 D57 D66 D79 +error(0.0006697986788568588423) D48 D57 D68 D70 D75 D77 L0 +error(0.0006697986788568588423) D48 D57 D68 D70 D79 L0 +error(0.0006697986788568588423) D48 D57 D70 D75 L0 +error(0.0006697986788568588423) D48 D57 D70 D79 L0 +error(0.0006697986788568588423) D48 D59 D68 D70 D74 D75 L0 +error(0.0006697986788568588423) D48 D59 D68 D70 D74 D77 D79 L0 +error(0.0006697986788568588423) D48 D61 D70 D75 L0 +error(0.0006697986788568588423) D48 D61 D70 D79 L0 +error(0.006657753962803452177) D48 D66 +error(0.0006697986788568588423) D48 D66 D74 D75 +error(0.0006697986788568588423) D48 D66 D74 D75 D77 +error(0.001338700097173320998) D48 D66 D75 D77 D79 +error(0.001338700097173320998) D48 D66 D75 D79 +error(0.001338700097173320998) D48 D68 D70 D75 D77 D79 L0 +error(0.001338700097173320998) D48 D68 D70 L0 +error(0.001338700097173320998) D48 D70 D75 D79 L0 +error(0.001338700097173320998) D48 D70 L0 +error(0.001338700097173320998) D49 D50 D53 D58 D59 D62 L0 +error(0.001338700097173320998) D49 D50 D53 D58 D59 D80 L0 +error(0.0006697986788568588423) D49 D50 D53 D58 D76 L0 +error(0.001338700097173320998) D49 D50 D53 D58 D77 D80 L0 +error(0.0006697986788568588423) D49 D50 D53 D59 D77 L0 +error(0.0006697986788568588423) D49 D50 D53 D62 D76 D77 L0 +error(0.001338700097173320998) D49 D50 D53 D62 D80 L0 +error(0.001338700097173320998) D49 D50 D53 D76 D77 D80 L0 +error(0.003340032800510209492) D49 D50 D53 L0 +error(0.0006697986788568588423) D49 D50 D55 D56 D65 D76 L0 +error(0.0006697986788568588423) D49 D50 D55 D65 D74 D76 L0 +error(0.0006697986788568588423) D49 D50 D56 D58 D59 D68 +error(0.0006697986788568588423) D49 D50 D56 D58 D68 D77 +error(0.001338700097173320998) D49 D50 D56 D65 D74 L0 +error(0.0006697986788568588423) D49 D50 D56 D65 D76 D77 L0 +error(0.0006697986788568588423) D49 D50 D58 D59 D68 D80 +error(0.0006697986788568588423) D49 D50 D58 D68 D77 D80 +error(0.001338700097173320998) D49 D50 D59 D68 D77 +error(0.0006697986788568588423) D49 D50 D59 D71 D74 D76 L0 +error(0.0006697986788568588423) D49 D50 D59 D71 D74 D77 D80 L0 +error(0.0006697986788568588423) D49 D50 D62 D71 D76 D77 L0 +error(0.0006697986788568588423) D49 D50 D62 D71 D80 L0 +error(0.0006697986788568588423) D49 D50 D65 D74 D76 D77 L0 +error(0.001338700097173320998) D49 D50 D65 L0 +error(0.001338700097173320998) D49 D50 D68 +error(0.001338700097173320998) D49 D50 D71 D76 D77 D80 L0 +error(0.001338700097173320998) D49 D50 D71 L0 +error(0.001338700097173320998) D49 D51 D53 D58 D60 D62 L0 +error(0.001338700097173320998) D49 D51 D53 D58 D60 D80 L0 +error(0.0006697986788568588423) D49 D51 D53 D58 D76 L0 +error(0.001338700097173320998) D49 D51 D53 D58 D78 D80 L0 +error(0.0006697986788568588423) D49 D51 D53 D60 D78 L0 +error(0.0006697986788568588423) D49 D51 D53 D62 D76 D78 L0 +error(0.001338700097173320998) D49 D51 D53 D62 D80 L0 +error(0.001338700097173320998) D49 D51 D53 D76 D78 D80 L0 +error(0.003340032800510209492) D49 D51 D53 L0 +error(0.0006697986788568588423) D49 D51 D58 D60 D69 +error(0.0006697986788568588423) D49 D51 D58 D60 D69 D80 +error(0.001338700097173320998) D49 D51 D58 D60 L0 +error(0.0006697986788568588423) D49 D51 D58 D69 D78 +error(0.0006697986788568588423) D49 D51 D58 D69 D78 D80 +error(0.0006697986788568588423) D49 D51 D58 D76 L0 +error(0.001338700097173320998) D49 D51 D58 D78 L0 +error(0.001338700097173320998) D49 D51 D60 D69 D78 +error(0.0006697986788568588423) D49 D51 D60 D71 D76 L0 +error(0.0006697986788568588423) D49 D51 D60 D71 D78 D80 L0 +error(0.0006697986788568588423) D49 D51 D60 D76 L0 +error(0.001338700097173320998) D49 D51 D60 D78 L0 +error(0.0006697986788568588423) D49 D51 D62 D71 D76 D78 L0 +error(0.0006697986788568588423) D49 D51 D62 D71 D80 L0 +error(0.001338700097173320998) D49 D51 D69 +error(0.001338700097173320998) D49 D51 D71 D76 D78 D80 L0 +error(0.001338700097173320998) D49 D51 D71 L0 +error(0.001338700097173320998) D49 D51 D76 D78 L0 +error(0.002673815958446297981) D49 D51 L0 +error(0.0006697986788568588423) D49 D53 D55 D58 D67 +error(0.0006697986788568588423) D49 D53 D55 D67 D76 +error(0.0006697986788568588423) D49 D53 D58 D59 D62 D71 +error(0.0006697986788568588423) D49 D53 D58 D59 D71 D80 +error(0.0006697986788568588423) D49 D53 D58 D60 D62 D71 +error(0.0006697986788568588423) D49 D53 D58 D60 D71 D80 +error(0.001338700097173320998) D49 D53 D58 D67 D76 +error(0.0006697986788568588423) D49 D53 D58 D67 D78 +error(0.004005357180252827609) D49 D53 D62 D71 D80 +error(0.001338700097173320998) D49 D53 D67 +error(0.0006697986788568588423) D49 D53 D67 D76 D78 +error(0.004005357180252827609) D49 D53 D71 +error(0.0006697986788568588423) D49 D54 D55 D64 L0 +error(0.0006697986788568588423) D49 D54 D64 D73 L0 +error(0.004005357180252827609) D49 D55 D64 D73 L0 +error(0.0006697986788568588423) D49 D55 D64 D76 L0 +error(0.001338700097173320998) D49 D58 D67 D73 +error(0.001338700097173320998) D49 D58 D67 D73 D74 +error(0.001338700097173320998) D49 D58 D67 D73 D76 D77 +error(0.001338700097173320998) D49 D58 D67 D73 D76 D78 +error(0.004005357180252827609) D49 D58 D67 D73 D80 +error(0.002673815958446297981) D49 D58 D67 D76 +error(0.0006697986788568588423) D49 D58 D67 D77 D80 +error(0.0006697986788568588423) D49 D58 D67 D78 D80 +error(0.0006697986788568588423) D49 D58 D68 D71 D73 D76 D77 L0 +error(0.0006697986788568588423) D49 D58 D68 D71 D73 D80 L0 +error(0.0006697986788568588423) D49 D58 D69 D71 D73 D76 D78 L0 +error(0.0006697986788568588423) D49 D58 D69 D71 D73 D80 L0 +error(0.0006697986788568588423) D49 D58 D69 D73 D76 D78 L0 +error(0.0006697986788568588423) D49 D58 D69 D73 L0 +error(0.0006697986788568588423) D49 D59 D68 D71 D74 D76 L0 +error(0.0006697986788568588423) D49 D59 D68 D71 D74 D77 D80 L0 +error(0.0006697986788568588423) D49 D60 D69 D71 D76 L0 +error(0.0006697986788568588423) D49 D60 D69 D71 D78 D80 L0 +error(0.0006697986788568588423) D49 D60 D69 D76 L0 +error(0.0006697986788568588423) D49 D60 D69 D78 L0 +error(0.0006697986788568588423) D49 D64 D73 D76 L0 +error(0.004005357180252827609) D49 D64 L0 +error(0.007978628588222850399) D49 D67 +error(0.0006697986788568588423) D49 D67 D73 D74 D76 +error(0.0006697986788568588423) D49 D67 D73 D76 +error(0.0006697986788568588423) D49 D67 D74 D76 D77 +error(0.001338700097173320998) D49 D67 D76 D77 D80 +error(0.0006697986788568588423) D49 D67 D76 D78 +error(0.001338700097173320998) D49 D67 D76 D78 D80 +error(0.001338700097173320998) D49 D68 D71 D76 D77 D80 L0 +error(0.001338700097173320998) D49 D68 D71 L0 +error(0.001338700097173320998) D49 D69 D71 D76 D78 D80 L0 +error(0.001338700097173320998) D49 D69 D71 L0 +error(0.001338700097173320998) D49 D69 D76 D78 L0 +error(0.001338700097173320998) D49 D69 L0 +error(0.0006697986788568588423) D50 D52 D56 D57 D66 D77 L0 +error(0.0006697986788568588423) D50 D52 D56 D66 D75 D77 L0 +error(0.001338700097173320998) D50 D52 D57 D66 D75 L0 +error(0.0006697986788568588423) D50 D52 D57 D66 D77 D79 L0 +error(0.001338700097173320998) D50 D52 D59 D61 L0 +error(0.0006697986788568588423) D50 D52 D59 D77 L0 +error(0.001338700097173320998) D50 D52 D59 D79 L0 +error(0.0006697986788568588423) D50 D52 D61 D75 D77 L0 +error(0.0006697986788568588423) D50 D52 D61 D75 D79 L0 +error(0.0006697986788568588423) D50 D52 D61 D79 L0 +error(0.0006697986788568588423) D50 D52 D66 D75 D77 D79 L0 +error(0.001338700097173320998) D50 D52 D66 L0 +error(0.001338700097173320998) D50 D52 D77 D79 L0 +error(0.002673815958446297981) D50 D52 L0 +error(0.0006697986788568588423) D50 D53 D56 D58 D67 D77 L0 +error(0.0006697986788568588423) D50 D53 D56 D67 D76 D77 L0 +error(0.001338700097173320998) D50 D53 D58 D67 D76 L0 +error(0.0006697986788568588423) D50 D53 D58 D67 D77 D80 L0 +error(0.001338700097173320998) D50 D53 D59 D62 L0 +error(0.0006697986788568588423) D50 D53 D59 D77 L0 +error(0.001338700097173320998) D50 D53 D59 D80 L0 +error(0.0006697986788568588423) D50 D53 D62 D76 D77 L0 +error(0.0006697986788568588423) D50 D53 D62 D76 D80 L0 +error(0.0006697986788568588423) D50 D53 D62 D80 L0 +error(0.0006697986788568588423) D50 D53 D67 D76 D77 D80 L0 +error(0.001338700097173320998) D50 D53 D67 L0 +error(0.001338700097173320998) D50 D53 D77 D80 L0 +error(0.002673815958446297981) D50 D53 L0 +error(0.0006697986788568588423) D50 D57 D59 D61 D70 L0 +error(0.0006697986788568588423) D50 D57 D59 D70 D79 L0 +error(0.0006697986788568588423) D50 D58 D59 D62 D71 L0 +error(0.0006697986788568588423) D50 D58 D59 D71 D80 L0 +error(0.0006697986788568588423) D50 D59 D61 D70 L0 +error(0.0006697986788568588423) D50 D59 D62 D71 L0 +error(0.004005357180252827609) D50 D59 D68 D74 +error(0.001338700097173320998) D50 D59 D68 D74 D75 +error(0.001338700097173320998) D50 D59 D68 D74 D76 +error(0.001338700097173320998) D50 D59 D68 D74 D77 D79 +error(0.001338700097173320998) D50 D59 D68 D74 D77 D80 +error(0.002673815958446297981) D50 D59 D68 D77 +error(0.0006697986788568588423) D50 D59 D68 D79 +error(0.0006697986788568588423) D50 D59 D68 D80 +error(0.0006697986788568588423) D50 D59 D70 D74 D77 D79 L0 +error(0.0006697986788568588423) D50 D59 D70 D74 L0 +error(0.0006697986788568588423) D50 D59 D70 D79 L0 +error(0.0006697986788568588423) D50 D59 D71 D74 D77 D80 L0 +error(0.0006697986788568588423) D50 D59 D71 D74 L0 +error(0.0006697986788568588423) D50 D59 D71 D80 L0 +error(0.0006697986788568588423) D50 D61 D70 D75 D77 L0 +error(0.0006697986788568588423) D50 D61 D70 D75 D79 L0 +error(0.001338700097173320998) D50 D61 D70 D79 L0 +error(0.0006697986788568588423) D50 D62 D71 D76 D77 L0 +error(0.0006697986788568588423) D50 D62 D71 D76 D80 L0 +error(0.001338700097173320998) D50 D62 D71 D80 L0 +error(0.007978628588222850399) D50 D68 +error(0.0006697986788568588423) D50 D68 D74 D75 D77 +error(0.0006697986788568588423) D50 D68 D74 D76 D77 +error(0.0006697986788568588423) D50 D68 D75 D77 D79 +error(0.0006697986788568588423) D50 D68 D76 D77 D80 +error(0.001338700097173320998) D50 D68 D77 D79 +error(0.001338700097173320998) D50 D68 D77 D80 +error(0.001338700097173320998) D50 D70 D77 D79 L0 +error(0.002673815958446297981) D50 D70 L0 +error(0.001338700097173320998) D50 D71 D77 D80 L0 +error(0.002673815958446297981) D50 D71 L0 +error(0.001338700097173320998) D51 D53 D58 D67 D76 L0 +error(0.0006697986788568588423) D51 D53 D58 D67 D78 D80 L0 +error(0.0006697986788568588423) D51 D53 D58 D67 D78 L0 +error(0.001338700097173320998) D51 D53 D60 D62 L0 +error(0.0006697986788568588423) D51 D53 D60 D78 L0 +error(0.001338700097173320998) D51 D53 D60 D80 L0 +error(0.0006697986788568588423) D51 D53 D62 D76 D78 L0 +error(0.0006697986788568588423) D51 D53 D62 D76 D80 L0 +error(0.0006697986788568588423) D51 D53 D62 D80 L0 +error(0.0006697986788568588423) D51 D53 D67 D76 D78 D80 L0 +error(0.0006697986788568588423) D51 D53 D67 D76 D78 L0 +error(0.001338700097173320998) D51 D53 D67 L0 +error(0.001338700097173320998) D51 D53 D78 D80 L0 +error(0.002673815958446297981) D51 D53 L0 +error(0.0006697986788568588423) D51 D58 D60 D62 D71 L0 +error(0.0006697986788568588423) D51 D58 D60 D71 D80 L0 +error(0.0006697986788568588423) D51 D60 D62 D71 L0 +error(0.004669790293214320931) D51 D60 D69 +error(0.001338700097173320998) D51 D60 D69 D76 +error(0.002673815958446297981) D51 D60 D69 D78 +error(0.001338700097173320998) D51 D60 D69 D78 D80 +error(0.0006697986788568588423) D51 D60 D69 D80 +error(0.0006697986788568588423) D51 D60 D71 D78 D80 L0 +error(0.0006697986788568588423) D51 D60 D71 D80 L0 +error(0.0006697986788568588423) D51 D60 D71 L0 +error(0.001338700097173320998) D51 D60 D78 L0 +error(0.002673815958446297981) D51 D60 L0 +error(0.0006697986788568588423) D51 D62 D71 D76 D78 L0 +error(0.0006697986788568588423) D51 D62 D71 D76 D80 L0 +error(0.001338700097173320998) D51 D62 D71 D80 L0 +error(0.006657753962803452177) D51 D69 +error(0.0006697986788568588423) D51 D69 D76 D78 +error(0.0006697986788568588423) D51 D69 D76 D78 D80 +error(0.001338700097173320998) D51 D69 D78 +error(0.001338700097173320998) D51 D69 D78 D80 +error(0.001338700097173320998) D51 D71 D78 D80 L0 +error(0.002673815958446297981) D51 D71 L0 +error(0.001338700097173320998) D51 D78 L0 +error(0.005995987492949031786) D51 L0 +error(0.0006697986788568588423) D52 D56 D57 D66 L0 +error(0.0006697986788568588423) D52 D56 D66 D75 L0 +error(0.0006697986788568588423) D52 D57 D59 D68 D79 L0 +error(0.004005357180252827609) D52 D57 D66 D75 L0 +error(0.0006697986788568588423) D52 D57 D66 D79 L0 +error(0.0006697986788568588423) D52 D57 D68 D77 D79 L0 +error(0.0006697986788568588423) D52 D59 D61 D70 +error(0.001338700097173320998) D52 D59 D68 D77 L0 +error(0.0006697986788568588423) D52 D59 D68 D79 L0 +error(0.0006697986788568588423) D52 D59 D70 D79 +error(0.0006697986788568588423) D52 D61 D70 +error(0.001338700097173320998) D52 D61 D70 D75 +error(0.001338700097173320998) D52 D61 D70 D75 D77 +error(0.004005357180252827609) D52 D61 D70 D75 D79 +error(0.002673815958446297981) D52 D61 D70 D79 +error(0.0006697986788568588423) D52 D61 D75 D79 L0 +error(0.0006697986788568588423) D52 D61 D75 L0 +error(0.0006697986788568588423) D52 D61 D79 L0 +error(0.002006705456917235505) D52 D61 L0 +error(0.0006697986788568588423) D52 D66 D75 D79 L0 +error(0.004005357180252827609) D52 D66 L0 +error(0.0006697986788568588423) D52 D68 D77 D79 L0 +error(0.001338700097173320998) D52 D68 L0 +error(0.006657753962803452177) D52 D70 +error(0.0006697986788568588423) D52 D70 D75 D77 D79 +error(0.0006697986788568588423) D52 D70 D75 D79 +error(0.0006697986788568588423) D52 D70 D77 D79 +error(0.001338700097173320998) D52 D70 D79 +error(0.001338700097173320998) D52 D79 L0 +error(0.003340032800510209492) D52 L0 +error(0.0006697986788568588423) D53 D58 D59 D68 D80 L0 +error(0.0006697986788568588423) D53 D58 D60 D69 D80 L0 +error(0.0006697986788568588423) D53 D58 D68 D77 D80 L0 +error(0.0006697986788568588423) D53 D58 D69 D78 D80 L0 +error(0.0006697986788568588423) D53 D59 D62 D71 +error(0.001338700097173320998) D53 D59 D68 D77 L0 +error(0.0006697986788568588423) D53 D59 D68 D80 L0 +error(0.0006697986788568588423) D53 D59 D71 D80 +error(0.0006697986788568588423) D53 D60 D62 D71 +error(0.001338700097173320998) D53 D60 D69 D78 L0 +error(0.0006697986788568588423) D53 D60 D69 D80 L0 +error(0.0006697986788568588423) D53 D60 D71 D80 +error(0.001338700097173320998) D53 D62 D71 D76 D77 +error(0.001338700097173320998) D53 D62 D71 D76 D78 +error(0.004005357180252827609) D53 D62 D71 D76 D80 +error(0.002673815958446297981) D53 D62 D71 D80 +error(0.0006697986788568588423) D53 D68 D77 D80 L0 +error(0.001338700097173320998) D53 D68 L0 +error(0.0006697986788568588423) D53 D69 D78 D80 L0 +error(0.001338700097173320998) D53 D69 L0 +error(0.006657753962803452177) D53 D71 +error(0.0006697986788568588423) D53 D71 D76 D77 D80 +error(0.0006697986788568588423) D53 D71 D76 D78 D80 +error(0.0006697986788568588423) D53 D71 D77 D80 +error(0.0006697986788568588423) D53 D71 D78 D80 +error(0.003340032800510209492) D54 +error(0.002673815958446297981) D54 D55 +error(0.003340032800510209492) D54 D55 D56 +error(0.001338700097173320998) D54 D55 D74 +error(0.002673815958446297981) D54 D56 +error(0.0006697986788568588423) D54 D63 D64 D65 D72 D73 L0 +error(0.0006697986788568588423) D54 D63 D64 D65 D74 L0 +error(0.0006697986788568588423) D54 D63 D64 D72 D73 L0 +error(0.0006697986788568588423) D54 D63 D64 L0 +error(0.0006697986788568588423) D54 D63 D65 D72 L0 +error(0.0006697986788568588423) D54 D63 D65 D74 L0 +error(0.0006697986788568588423) D54 D63 D72 L0 +error(0.0006697986788568588423) D54 D63 L0 +error(0.006657753962803452177) D54 D72 +error(0.001338700097173320998) D54 D72 D73 +error(0.001338700097173320998) D54 D73 +error(0.001338700097173320998) D54 D73 D74 +error(0.005333333333333313206) D54 D74 +error(0.003340032800510209492) D55 D56 D58 +error(0.001338700097173320998) D55 D56 D76 +error(0.002673815958446297981) D55 D58 +error(0.0006697986788568588423) D55 D64 D65 D67 D73 D74 L0 +error(0.0006697986788568588423) D55 D64 D65 D67 D76 L0 +error(0.0006697986788568588423) D55 D64 D67 D73 L0 +error(0.0006697986788568588423) D55 D64 D67 D76 L0 +error(0.001338700097173320998) D55 D72 +error(0.006657753962803452177) D55 D73 +error(0.001338700097173320998) D55 D73 D74 +error(0.001338700097173320998) D55 D74 D76 +error(0.005333333333333313206) D55 D76 +error(0.002673815958446297981) D56 D57 +error(0.003340032800510209492) D56 D57 D59 +error(0.001338700097173320998) D56 D57 D77 +error(0.003340032800510209492) D56 D58 D59 +error(0.001338700097173320998) D56 D58 D77 +error(0.0006697986788568588423) D56 D65 D66 D68 D72 D74 D75 L0 +error(0.0006697986788568588423) D56 D65 D66 D68 D72 D77 L0 +error(0.0006697986788568588423) D56 D65 D66 D72 D74 D75 L0 +error(0.0006697986788568588423) D56 D65 D66 D72 L0 +error(0.0006697986788568588423) D56 D65 D67 D68 D72 D74 D76 L0 +error(0.0006697986788568588423) D56 D65 D67 D68 D72 D77 L0 +error(0.001338700097173320998) D56 D72 +error(0.001338700097173320998) D56 D72 D73 +error(0.001338700097173320998) D56 D72 D74 D75 +error(0.001338700097173320998) D56 D72 D74 D76 +error(0.004005357180252827609) D56 D72 D77 +error(0.007978628588222850399) D56 D74 +error(0.001338700097173320998) D56 D75 +error(0.001338700097173320998) D56 D75 D77 +error(0.001338700097173320998) D56 D76 D77 +error(0.003340032800510209492) D57 D59 D61 +error(0.001338700097173320998) D57 D59 D79 +error(0.002673815958446297981) D57 D61 +error(0.0006697986788568588423) D57 D61 D70 L0 +error(0.0006697986788568588423) D57 D66 D68 D70 D75 D77 L0 +error(0.0006697986788568588423) D57 D66 D68 D70 D79 L0 +error(0.0006697986788568588423) D57 D66 D70 D75 L0 +error(0.0006697986788568588423) D57 D66 D70 D79 L0 +error(0.0006697986788568588423) D57 D70 D79 L0 +error(0.001338700097173320998) D57 D74 +error(0.006657753962803452177) D57 D75 +error(0.001338700097173320998) D57 D75 D77 +error(0.001338700097173320998) D57 D77 D79 +error(0.005333333333333313206) D57 D79 +error(0.003340032800510209492) D58 D59 D62 +error(0.001338700097173320998) D58 D59 D80 +error(0.002673815958446297981) D58 D60 +error(0.003340032800510209492) D58 D60 D62 +error(0.0006697986788568588423) D58 D60 D69 L0 +error(0.001338700097173320998) D58 D60 D80 +error(0.0006697986788568588423) D58 D67 D68 D71 D73 D76 D77 L0 +error(0.0006697986788568588423) D58 D67 D68 D71 D73 D80 L0 +error(0.0006697986788568588423) D58 D67 D69 D71 D73 D76 D78 L0 +error(0.0006697986788568588423) D58 D67 D69 D71 D73 D80 L0 +error(0.0006697986788568588423) D58 D67 D69 D73 D76 D78 L0 +error(0.0006697986788568588423) D58 D67 D69 D73 L0 +error(0.0006697986788568588423) D58 D69 D78 L0 +error(0.001338700097173320998) D58 D73 +error(0.001338700097173320998) D58 D73 D74 +error(0.001338700097173320998) D58 D73 D76 D77 +error(0.001338700097173320998) D58 D73 D76 D78 +error(0.004005357180252827609) D58 D73 D80 +error(0.007978628588222850399) D58 D76 +error(0.001338700097173320998) D58 D77 D80 +error(0.001338700097173320998) D58 D78 +error(0.001338700097173320998) D58 D78 D80 +error(0.002673815958446297981) D59 D61 +error(0.002673815958446297981) D59 D62 +error(0.0006697986788568588423) D59 D68 D70 D74 D77 D79 L0 +error(0.0006697986788568588423) D59 D68 D70 D74 L0 +error(0.0006697986788568588423) D59 D68 D71 D74 D77 D80 L0 +error(0.0006697986788568588423) D59 D68 D71 D74 L0 +error(0.004005357180252827609) D59 D74 +error(0.001338700097173320998) D59 D74 D75 +error(0.001338700097173320998) D59 D74 D76 +error(0.001338700097173320998) D59 D74 D77 D79 +error(0.001338700097173320998) D59 D74 D77 D80 +error(0.007978628588222850399) D59 D77 +error(0.001338700097173320998) D59 D79 +error(0.001338700097173320998) D59 D80 +error(0.005995987492949031786) D60 +error(0.002673815958446297981) D60 D62 +error(0.0006697986788568588423) D60 D69 D71 D78 D80 L0 +error(0.0006697986788568588423) D60 D69 D71 L0 +error(0.004669790293214320931) D60 D69 D78 L0 +error(0.001338700097173320998) D60 D69 L0 +error(0.001338700097173320998) D60 D76 +error(0.006657753962803452177) D60 D78 +error(0.001338700097173320998) D60 D78 D80 +error(0.001338700097173320998) D60 D80 +error(0.002006705456917235505) D61 +error(0.0006697986788568588423) D61 D70 D75 D79 L0 +error(0.0006697986788568588423) D61 D70 D75 L0 +error(0.001338700097173320998) D61 D70 D79 L0 +error(0.0006697986788568588423) D61 D70 L0 +error(0.001338700097173320998) D61 D75 +error(0.001338700097173320998) D61 D75 D77 +error(0.004005357180252827609) D61 D75 D79 +error(0.006657753962803452177) D61 D79 +error(0.001338700097173320998) D62 D76 D77 +error(0.001338700097173320998) D62 D76 D78 +error(0.004005357180252827609) D62 D76 D80 +error(0.006657753962803452177) D62 D80 +error(0.001338700097173320998) D63 D64 D65 D72 D73 D74 L0 +error(0.001338700097173320998) D63 D64 D65 D72 D73 L0 +error(0.002006705456917235505) D63 D64 D65 D72 L0 +error(0.0006697986788568588423) D63 D64 D65 D73 L0 +error(0.002006705456917235505) D63 D64 D65 D74 L0 +error(0.004669790293214320931) D63 D64 D65 L0 +error(0.001338700097173320998) D63 D64 D67 D72 D73 D82 +error(0.001338700097173320998) D63 D64 D67 D72 D82 +error(0.001338700097173320998) D63 D64 D67 D73 D82 +error(0.001338700097173320998) D63 D64 D67 D82 +error(0.001338700097173320998) D63 D64 D72 D73 L0 +error(0.002006705456917235505) D63 D64 D72 L0 +error(0.001338700097173320998) D63 D64 D73 D83 L0 +error(0.002006705456917235505) D63 D64 D73 L0 +error(0.001338700097173320998) D63 D64 D74 D83 L0 +error(0.002673815958446297981) D63 D64 D83 L0 +error(0.004005357180252827609) D63 D64 L0 +error(0.001338700097173320998) D63 D65 D72 D74 L0 +error(0.002673815958446297981) D63 D65 D72 D81 +error(0.002006705456917235505) D63 D65 D72 L0 +error(0.002006705456917235505) D63 D65 D74 L0 +error(0.002673815958446297981) D63 D65 D81 +error(0.004005357180252827609) D63 D65 L0 +error(0.0006697986788568588423) D63 D68 D72 D73 D74 D83 L0 +error(0.0006697986788568588423) D63 D68 D72 D73 D83 L0 +error(0.0006697986788568588423) D63 D68 D72 D74 D83 L0 +error(0.0006697986788568588423) D63 D68 D72 D83 L0 +error(0.004005357180252827609) D63 D68 D74 D83 L0 +error(0.004005357180252827609) D63 D68 D83 L0 +error(0.01060977777777773884) D63 D72 D81 +error(0.001338700097173320998) D63 D72 D82 D83 L0 +error(0.001338700097173320998) D63 D72 D82 L0 +error(0.001338700097173320998) D63 D72 D83 L0 +error(0.003340032800510209492) D63 D72 L0 +error(0.001338700097173320998) D63 D73 D82 D83 L0 +error(0.001338700097173320998) D63 D73 D82 L0 +error(0.001338700097173320998) D63 D74 D83 L0 +error(0.01060977777777773884) D63 D81 +error(0.002673815958446297981) D63 D82 D83 L0 +error(0.002673815958446297981) D63 D82 L0 +error(0.002673815958446297981) D63 D83 L0 +error(0.003340032800510209492) D63 L0 +error(0.001338700097173320998) D64 D65 D67 D73 D74 D76 L0 +error(0.001338700097173320998) D64 D65 D67 D73 D74 L0 +error(0.002006705456917235505) D64 D65 D67 D73 L0 +error(0.0006697986788568588423) D64 D65 D67 D74 L0 +error(0.002006705456917235505) D64 D65 D67 D76 L0 +error(0.004669790293214320931) D64 D65 D67 L0 +error(0.0006697986788568588423) D64 D65 D68 D72 D73 D74 D83 +error(0.0006697986788568588423) D64 D65 D68 D72 D73 D83 +error(0.0006697986788568588423) D64 D65 D68 D73 D74 D83 +error(0.0006697986788568588423) D64 D65 D68 D73 D83 +error(0.001338700097173320998) D64 D65 D68 D74 D83 +error(0.001338700097173320998) D64 D65 D68 D83 +error(0.002673815958446297981) D64 D65 D72 D81 L0 +error(0.001338700097173320998) D64 D65 D74 D85 L0 +error(0.001338700097173320998) D64 D65 D76 D85 L0 +error(0.002673815958446297981) D64 D65 D81 L0 +error(0.002673815958446297981) D64 D65 D85 L0 +error(0.001338700097173320998) D64 D67 D73 D76 L0 +error(0.002006705456917235505) D64 D67 D73 L0 +error(0.002006705456917235505) D64 D67 D76 L0 +error(0.004005357180252827609) D64 D67 L0 +error(0.0006697986788568588423) D64 D71 D73 D74 D76 D85 L0 +error(0.0006697986788568588423) D64 D71 D73 D74 D85 L0 +error(0.0006697986788568588423) D64 D71 D73 D76 D85 L0 +error(0.0006697986788568588423) D64 D71 D73 D85 L0 +error(0.004005357180252827609) D64 D71 D76 D85 L0 +error(0.004005357180252827609) D64 D71 D85 L0 +error(0.01060977777777773884) D64 D73 D82 +error(0.001338700097173320998) D64 D73 D83 D85 L0 +error(0.001338700097173320998) D64 D73 D85 L0 +error(0.001338700097173320998) D64 D74 D83 D85 L0 +error(0.001338700097173320998) D64 D76 D85 L0 +error(0.01060977777777773884) D64 D82 +error(0.002673815958446297981) D64 D83 D85 L0 +error(0.002673815958446297981) D64 D85 L0 +error(0.001338700097173320998) D65 D66 D68 D74 D75 D77 L0 +error(0.001338700097173320998) D65 D66 D68 D74 D75 L0 +error(0.002006705456917235505) D65 D66 D68 D74 L0 +error(0.0006697986788568588423) D65 D66 D68 D75 L0 +error(0.002006705456917235505) D65 D66 D68 D77 L0 +error(0.004669790293214320931) D65 D66 D68 L0 +error(0.001338700097173320998) D65 D66 D70 D74 D75 D84 +error(0.001338700097173320998) D65 D66 D70 D74 D84 +error(0.001338700097173320998) D65 D66 D70 D75 D84 +error(0.001338700097173320998) D65 D66 D70 D84 +error(0.001338700097173320998) D65 D66 D74 D75 L0 +error(0.002006705456917235505) D65 D66 D74 L0 +error(0.001338700097173320998) D65 D66 D75 D86 L0 +error(0.002006705456917235505) D65 D66 D75 L0 +error(0.001338700097173320998) D65 D66 D77 D86 L0 +error(0.002673815958446297981) D65 D66 D86 L0 +error(0.004005357180252827609) D65 D66 L0 +error(0.001338700097173320998) D65 D67 D68 D74 D76 D77 L0 +error(0.001338700097173320998) D65 D67 D68 D74 D76 L0 +error(0.002006705456917235505) D65 D67 D68 D74 L0 +error(0.0006697986788568588423) D65 D67 D68 D76 L0 +error(0.002006705456917235505) D65 D67 D68 D77 L0 +error(0.004669790293214320931) D65 D67 D68 L0 +error(0.0006697986788568588423) D65 D67 D71 D73 D74 D76 D85 +error(0.0006697986788568588423) D65 D67 D71 D73 D74 D85 +error(0.0006697986788568588423) D65 D67 D71 D74 D76 D85 +error(0.0006697986788568588423) D65 D67 D71 D74 D85 +error(0.001338700097173320998) D65 D67 D71 D76 D85 +error(0.001338700097173320998) D65 D67 D71 D85 +error(0.0006697986788568588423) D65 D67 D72 D73 D82 L0 +error(0.0006697986788568588423) D65 D67 D72 D82 L0 +error(0.002006705456917235505) D65 D67 D73 D82 L0 +error(0.001338700097173320998) D65 D67 D76 D86 L0 +error(0.001338700097173320998) D65 D67 D77 D86 L0 +error(0.002006705456917235505) D65 D67 D82 L0 +error(0.002673815958446297981) D65 D67 D86 L0 +error(0.0006697986788568588423) D65 D68 D72 D74 D83 +error(0.0006697986788568588423) D65 D68 D72 D83 +error(0.002006705456917235505) D65 D68 D74 D83 +error(0.002006705456917235505) D65 D68 D83 +error(0.005333333333333313206) D65 D72 D81 L0 +error(0.0006697986788568588423) D65 D74 D75 D77 D86 L0 +error(0.0006697986788568588423) D65 D74 D75 D86 L0 +error(0.0006697986788568588423) D65 D74 D76 D77 D86 L0 +error(0.0006697986788568588423) D65 D74 D76 D86 L0 +error(0.01322685654994845347) D65 D74 D83 +error(0.001338700097173320998) D65 D74 D84 D86 L0 +error(0.001338700097173320998) D65 D74 D84 L0 +error(0.001338700097173320998) D65 D74 D85 D86 L0 +error(0.001338700097173320998) D65 D75 D84 D86 L0 +error(0.001338700097173320998) D65 D75 D84 L0 +error(0.001338700097173320998) D65 D76 D85 D86 L0 +error(0.004005357180252827609) D65 D77 D86 L0 +error(0.005333333333333313206) D65 D81 L0 +error(0.01322685654994845347) D65 D83 +error(0.002673815958446297981) D65 D84 D86 L0 +error(0.002673815958446297981) D65 D84 L0 +error(0.002673815958446297981) D65 D85 D86 L0 +error(0.004005357180252827609) D65 D86 L0 +error(0.001338700097173320998) D66 D68 D70 D75 D77 D79 L0 +error(0.001338700097173320998) D66 D68 D70 D75 D77 L0 +error(0.002006705456917235505) D66 D68 D70 D75 L0 +error(0.0006697986788568588423) D66 D68 D70 D77 L0 +error(0.002006705456917235505) D66 D68 D70 D79 L0 +error(0.004669790293214320931) D66 D68 D70 L0 +error(0.0006697986788568588423) D66 D68 D74 D75 D77 D86 +error(0.0006697986788568588423) D66 D68 D74 D75 D86 +error(0.002673815958446297981) D66 D68 D74 D83 L0 +error(0.0006697986788568588423) D66 D68 D75 D77 D86 +error(0.0006697986788568588423) D66 D68 D75 D86 +error(0.001338700097173320998) D66 D68 D77 D86 +error(0.001338700097173320998) D66 D68 D77 D88 L0 +error(0.001338700097173320998) D66 D68 D79 D88 L0 +error(0.002673815958446297981) D66 D68 D83 L0 +error(0.001338700097173320998) D66 D68 D86 +error(0.002673815958446297981) D66 D68 D88 L0 +error(0.0006697986788568588423) D66 D70 D75 D77 D79 D88 +error(0.0006697986788568588423) D66 D70 D75 D77 D88 +error(0.0006697986788568588423) D66 D70 D75 D79 D88 +error(0.001338700097173320998) D66 D70 D75 D79 L0 +error(0.0006697986788568588423) D66 D70 D75 D88 +error(0.002006705456917235505) D66 D70 D75 L0 +error(0.004005357180252827609) D66 D70 D79 D88 +error(0.002006705456917235505) D66 D70 D79 L0 +error(0.004005357180252827609) D66 D70 D88 +error(0.004005357180252827609) D66 D70 L0 +error(0.01060977777777773884) D66 D75 D84 +error(0.001338700097173320998) D66 D75 D86 D88 L0 +error(0.001338700097173320998) D66 D75 D88 L0 +error(0.001338700097173320998) D66 D77 D86 D88 L0 +error(0.001338700097173320998) D66 D79 D88 L0 +error(0.01060977777777773884) D66 D84 +error(0.002673815958446297981) D66 D86 D88 L0 +error(0.002673815958446297981) D66 D88 L0 +error(0.001338700097173320998) D67 D68 D71 D76 D77 D80 L0 +error(0.001338700097173320998) D67 D68 D71 D76 D77 L0 +error(0.002006705456917235505) D67 D68 D71 D76 L0 +error(0.0006697986788568588423) D67 D68 D71 D77 L0 +error(0.002006705456917235505) D67 D68 D71 D80 L0 +error(0.004669790293214320931) D67 D68 D71 L0 +error(0.0006697986788568588423) D67 D68 D73 D74 D83 L0 +error(0.0006697986788568588423) D67 D68 D73 D83 L0 +error(0.0006697986788568588423) D67 D68 D74 D76 D77 D86 +error(0.0006697986788568588423) D67 D68 D74 D76 D86 +error(0.002006705456917235505) D67 D68 D74 D83 L0 +error(0.0006697986788568588423) D67 D68 D76 D77 D86 +error(0.0006697986788568588423) D67 D68 D76 D86 +error(0.001338700097173320998) D67 D68 D77 D86 +error(0.001338700097173320998) D67 D68 D77 D89 L0 +error(0.001338700097173320998) D67 D68 D80 D89 L0 +error(0.002006705456917235505) D67 D68 D83 L0 +error(0.001338700097173320998) D67 D68 D86 +error(0.002673815958446297981) D67 D68 D89 L0 +error(0.001338700097173320998) D67 D69 D71 D76 D78 D80 L0 +error(0.001338700097173320998) D67 D69 D71 D76 D78 L0 +error(0.002006705456917235505) D67 D69 D71 D76 L0 +error(0.0006697986788568588423) D67 D69 D71 D78 L0 +error(0.002006705456917235505) D67 D69 D71 D80 L0 +error(0.004669790293214320931) D67 D69 D71 L0 +error(0.001338700097173320998) D67 D69 D76 D78 D87 +error(0.001338700097173320998) D67 D69 D76 D78 L0 +error(0.001338700097173320998) D67 D69 D76 D87 +error(0.002006705456917235505) D67 D69 D76 L0 +error(0.001338700097173320998) D67 D69 D78 D87 +error(0.001338700097173320998) D67 D69 D78 D89 L0 +error(0.002006705456917235505) D67 D69 D78 L0 +error(0.001338700097173320998) D67 D69 D80 D89 L0 +error(0.001338700097173320998) D67 D69 D87 +error(0.002673815958446297981) D67 D69 D89 L0 +error(0.004005357180252827609) D67 D69 L0 +error(0.0006697986788568588423) D67 D71 D73 D76 D85 +error(0.0006697986788568588423) D67 D71 D73 D85 +error(0.0006697986788568588423) D67 D71 D76 D77 D80 D89 +error(0.0006697986788568588423) D67 D71 D76 D77 D89 +error(0.0006697986788568588423) D67 D71 D76 D78 D80 D89 +error(0.0006697986788568588423) D67 D71 D76 D78 D89 +error(0.002006705456917235505) D67 D71 D76 D85 +error(0.004005357180252827609) D67 D71 D80 D89 +error(0.002006705456917235505) D67 D71 D85 +error(0.004005357180252827609) D67 D71 D89 +error(0.0006697986788568588423) D67 D72 D73 D82 L0 +error(0.0006697986788568588423) D67 D72 D82 L0 +error(0.004669790293214320931) D67 D73 D82 L0 +error(0.01322685654994845347) D67 D76 D85 +error(0.001338700097173320998) D67 D76 D86 D89 L0 +error(0.001338700097173320998) D67 D76 D87 D89 L0 +error(0.001338700097173320998) D67 D76 D87 L0 +error(0.001338700097173320998) D67 D77 D86 D89 L0 +error(0.001338700097173320998) D67 D78 D87 D89 L0 +error(0.001338700097173320998) D67 D78 D87 L0 +error(0.004669790293214320931) D67 D82 L0 +error(0.01322685654994845347) D67 D85 +error(0.002673815958446297981) D67 D86 D89 L0 +error(0.002673815958446297981) D67 D87 D89 L0 +error(0.002673815958446297981) D67 D87 L0 +error(0.0006697986788568588423) D68 D70 D74 D75 D84 L0 +error(0.0006697986788568588423) D68 D70 D74 D84 L0 +error(0.002006705456917235505) D68 D70 D75 D84 L0 +error(0.001338700097173320998) D68 D70 D77 D79 L0 +error(0.002006705456917235505) D68 D70 D77 L0 +error(0.002006705456917235505) D68 D70 D79 L0 +error(0.002006705456917235505) D68 D70 D84 L0 +error(0.004005357180252827609) D68 D70 L0 +error(0.0006697986788568588423) D68 D71 D74 D76 D85 L0 +error(0.0006697986788568588423) D68 D71 D74 D85 L0 +error(0.002006705456917235505) D68 D71 D76 D85 L0 +error(0.001338700097173320998) D68 D71 D77 D80 L0 +error(0.002006705456917235505) D68 D71 D77 L0 +error(0.002006705456917235505) D68 D71 D80 L0 +error(0.002006705456917235505) D68 D71 D85 L0 +error(0.004005357180252827609) D68 D71 L0 +error(0.0006697986788568588423) D68 D75 D77 D79 D88 L0 +error(0.0006697986788568588423) D68 D75 D77 D88 L0 +error(0.0006697986788568588423) D68 D76 D77 D80 D89 L0 +error(0.0006697986788568588423) D68 D76 D77 D89 L0 +error(0.0006697986788568588423) D68 D77 D79 D88 L0 +error(0.0006697986788568588423) D68 D77 D80 D89 L0 +error(0.01322685654994845347) D68 D77 D86 +error(0.002006705456917235505) D68 D77 D88 L0 +error(0.002006705456917235505) D68 D77 D89 L0 +error(0.002673815958446297981) D68 D79 D88 L0 +error(0.002673815958446297981) D68 D80 D89 L0 +error(0.01322685654994845347) D68 D86 +error(0.004005357180252827609) D68 D88 L0 +error(0.004005357180252827609) D68 D89 L0 +error(0.002673815958446297981) D69 D71 D76 D85 L0 +error(0.001338700097173320998) D69 D71 D78 D80 L0 +error(0.002006705456917235505) D69 D71 D78 L0 +error(0.002006705456917235505) D69 D71 D80 L0 +error(0.002673815958446297981) D69 D71 D85 L0 +error(0.004005357180252827609) D69 D71 L0 +error(0.0006697986788568588423) D69 D76 D78 D80 D89 L0 +error(0.0006697986788568588423) D69 D76 D78 D89 L0 +error(0.0006697986788568588423) D69 D78 D80 D89 L0 +error(0.01060977777777773884) D69 D78 D87 +error(0.002006705456917235505) D69 D78 D89 L0 +error(0.004005357180252827609) D69 D78 L0 +error(0.002673815958446297981) D69 D80 D89 L0 +error(0.01060977777777773884) D69 D87 +error(0.004005357180252827609) D69 D89 L0 +error(0.007318633932043431753) D69 L0 +error(0.0006697986788568588423) D70 D74 D75 D84 L0 +error(0.0006697986788568588423) D70 D74 D84 L0 +error(0.0006697986788568588423) D70 D75 D77 D86 L0 +error(0.004669790293214320931) D70 D75 D84 L0 +error(0.0006697986788568588423) D70 D75 D86 L0 +error(0.0006697986788568588423) D70 D77 D79 D88 +error(0.002006705456917235505) D70 D77 D86 L0 +error(0.0006697986788568588423) D70 D77 D88 +error(0.009953312530086681764) D70 D79 D88 +error(0.004005357180252827609) D70 D79 L0 +error(0.004669790293214320931) D70 D84 L0 +error(0.002006705456917235505) D70 D86 L0 +error(0.009953312530086681764) D70 D88 +error(0.004669790293214320931) D70 L0 +error(0.0006697986788568588423) D71 D76 D77 D86 L0 +error(0.0006697986788568588423) D71 D76 D78 D87 L0 +error(0.0006697986788568588423) D71 D76 D86 L0 +error(0.0006697986788568588423) D71 D76 D87 L0 +error(0.0006697986788568588423) D71 D77 D80 D89 +error(0.002006705456917235505) D71 D77 D86 L0 +error(0.0006697986788568588423) D71 D77 D89 +error(0.0006697986788568588423) D71 D78 D80 D89 +error(0.002006705456917235505) D71 D78 D87 L0 +error(0.0006697986788568588423) D71 D78 D89 +error(0.009295966703663446212) D71 D80 D89 +error(0.002006705456917235505) D71 D86 L0 +error(0.002006705456917235505) D71 D87 L0 +error(0.009295966703663446212) D71 D89 +error(0.01906422791000844316) D72 +error(0.004005357180252827609) D72 D73 +error(0.003340032800510209492) D72 D73 D74 +error(0.002673815958446297981) D72 D74 +error(0.001338700097173320998) D72 D81 D82 D83 L0 +error(0.001338700097173320998) D72 D81 D82 L0 +error(0.001338700097173320998) D72 D81 D83 L0 +error(0.001338700097173320998) D72 D81 L0 +error(0.01582994014814808822) D73 +error(0.001338700097173320998) D73 D74 +error(0.003340032800510209492) D73 D74 D76 +error(0.002673815958446297981) D73 D76 +error(0.001338700097173320998) D73 D82 D83 D85 L0 +error(0.001338700097173320998) D73 D82 D85 L0 +error(0.02099442078656782798) D74 +error(0.004005357180252827609) D74 D75 +error(0.003340032800510209492) D74 D75 D77 +error(0.001338700097173320998) D74 D76 +error(0.003340032800510209492) D74 D76 D77 +error(0.001338700097173320998) D74 D83 D84 D86 L0 +error(0.001338700097173320998) D74 D83 D84 L0 +error(0.001338700097173320998) D74 D83 D85 D86 L0 +error(0.01582994014814808822) D75 +error(0.001338700097173320998) D75 D77 +error(0.003340032800510209492) D75 D77 D79 +error(0.002673815958446297981) D75 D79 +error(0.0006697986788568588423) D75 D79 D88 L0 +error(0.001338700097173320998) D75 D84 D86 D88 L0 +error(0.001338700097173320998) D75 D84 D88 L0 +error(0.0006697986788568588423) D75 D88 L0 +error(0.02099442078656782798) D76 +error(0.001338700097173320998) D76 D77 +error(0.003340032800510209492) D76 D77 D80 +error(0.004005357180252827609) D76 D78 +error(0.003340032800510209492) D76 D78 D80 +error(0.0006697986788568588423) D76 D78 D87 L0 +error(0.001338700097173320998) D76 D85 D86 D89 L0 +error(0.001338700097173320998) D76 D85 D87 D89 L0 +error(0.001338700097173320998) D76 D85 D87 L0 +error(0.0006697986788568588423) D76 D87 L0 +error(0.01970848819953020456) D77 +error(0.002673815958446297981) D77 D79 +error(0.002673815958446297981) D77 D80 +error(0.001338700097173320998) D77 D86 D88 L0 +error(0.001338700097173320998) D77 D86 D89 L0 +error(0.01647853308100971984) D78 +error(0.002673815958446297981) D78 D80 +error(0.001338700097173320998) D78 D87 D89 L0 +error(0.005995987492949031786) D78 D87 L0 +error(0.01518047719643240284) D79 +error(0.003340032800510209492) D79 D88 L0 +error(0.01322685654994845347) D80 +error(0.001338700097173320998) D81 D82 D83 L0 +error(0.001338700097173320998) D81 D82 L0 +error(0.001338700097173320998) D81 D83 L0 +error(0.001338700097173320998) D81 L0 +error(0.001338700097173320998) D82 D83 D85 L0 +error(0.001338700097173320998) D82 D85 L0 +error(0.001338700097173320998) D83 D84 D86 L0 +error(0.001338700097173320998) D83 D84 L0 +error(0.001338700097173320998) D83 D85 D86 L0 +error(0.001338700097173320998) D84 D86 D88 L0 +error(0.001338700097173320998) D84 D88 L0 +error(0.001338700097173320998) D85 D86 D89 L0 +error(0.001338700097173320998) D85 D87 D89 L0 +error(0.001338700097173320998) D85 D87 L0 +error(0.001338700097173320998) D86 D88 L0 +error(0.001338700097173320998) D86 D89 L0 +error(0.001338700097173320998) D87 D89 L0 +error(0.005995987492949031786) D87 L0 +error(0.003340032800510209492) D88 L0 diff --git a/libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_Z.dem b/libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_Z.dem new file mode 100644 index 000000000..75c7c8dc7 --- /dev/null +++ b/libs/qec/python/tests/data/superdense_golden_d5_r5_allnoisy_Z.dem @@ -0,0 +1,2964 @@ +# Reference superdense color-code DEM, d=5, 5 rounds, DEPOLARIZE2(0.01) +# per CX, ALL ROUNDS NOISY (physically stricter convention). +# Generator: reference superdense construction (superdense_memory kernel, +# cudaq.dem_from_kernel). The perfect-final-round originals are +# byte-reproduced by the same generator with its two noise guards restored +# (R > 1 and r < R - 1); here both are relaxed to p_cx > 0.0 so every +# stabilizer round is noisy. +error(0.003340032800510209492) D0 +error(0.001338700097173320998) D0 D1 +error(0.001338700097173320998) D0 D1 D2 +error(0.001338700097173320998) D0 D1 D2 D11 +error(0.001338700097173320998) D0 D1 D10 +error(0.001338700097173320998) D0 D1 D10 D20 +error(0.001338700097173320998) D0 D1 D11 D20 +error(0.002673815958446297981) D0 D1 D20 +error(0.001338700097173320998) D0 D2 +error(0.001338700097173320998) D0 D2 D11 +error(0.003340032800510209492) D0 D9 +error(0.0006697986788568588423) D0 D9 D10 +error(0.0006697986788568588423) D0 D9 D10 D11 D18 D19 +error(0.0006697986788568588423) D0 D9 D10 D11 D20 +error(0.0006697986788568588423) D0 D9 D10 D18 D19 +error(0.0006697986788568588423) D0 D9 D11 D18 +error(0.0006697986788568588423) D0 D9 D11 D20 +error(0.009953312530086681764) D0 D9 D18 +error(0.001338700097173320998) D0 D9 D18 D19 +error(0.001338700097173320998) D0 D9 D19 +error(0.001338700097173320998) D0 D9 D19 D20 +error(0.005333333333333313206) D0 D9 D20 +error(0.0006697986788568588423) D0 D10 +error(0.0006697986788568588423) D0 D10 D11 D18 D19 +error(0.0006697986788568588423) D0 D10 D11 D20 +error(0.0006697986788568588423) D0 D10 D18 D19 +error(0.001338700097173320998) D0 D10 D19 +error(0.001338700097173320998) D0 D10 D19 D20 +error(0.0006697986788568588423) D0 D11 D18 +error(0.002006705456917235505) D0 D11 D20 +error(0.009953312530086681764) D0 D18 +error(0.001338700097173320998) D0 D18 D19 +error(0.002673815958446297981) D0 D19 +error(0.002673815958446297981) D0 D19 D20 +error(0.006657753962803452177) D0 D20 +error(0.001338700097173320998) D1 D2 D4 +error(0.001338700097173320998) D1 D2 D4 D13 +error(0.001338700097173320998) D1 D2 D11 D22 +error(0.001338700097173320998) D1 D2 D13 D22 +error(0.002673815958446297981) D1 D2 D22 +error(0.001338700097173320998) D1 D4 +error(0.001338700097173320998) D1 D4 D13 +error(0.0006697986788568588423) D1 D10 D11 D13 D19 D20 +error(0.0006697986788568588423) D1 D10 D11 D13 D22 +error(0.0006697986788568588423) D1 D10 D11 D18 +error(0.0006697986788568588423) D1 D10 D11 D19 D20 +error(0.0006697986788568588423) D1 D10 D13 D19 +error(0.0006697986788568588423) D1 D10 D13 D22 +error(0.002006705456917235505) D1 D10 D18 +error(0.009953312530086681764) D1 D10 D19 +error(0.001338700097173320998) D1 D10 D19 D20 +error(0.001338700097173320998) D1 D10 D20 D22 +error(0.005333333333333313206) D1 D10 D22 +error(0.0006697986788568588423) D1 D11 D13 D19 D20 +error(0.0006697986788568588423) D1 D11 D13 D22 +error(0.0006697986788568588423) D1 D11 D18 +error(0.0006697986788568588423) D1 D11 D19 D20 +error(0.001338700097173320998) D1 D11 D20 D22 +error(0.0006697986788568588423) D1 D13 D19 +error(0.002006705456917235505) D1 D13 D22 +error(0.002006705456917235505) D1 D18 +error(0.009953312530086681764) D1 D19 +error(0.001338700097173320998) D1 D19 D20 +error(0.002673815958446297981) D1 D20 D22 +error(0.006657753962803452177) D1 D22 +error(0.001338700097173320998) D2 D3 +error(0.001338700097173320998) D2 D3 D5 +error(0.001338700097173320998) D2 D3 D5 D14 +error(0.001338700097173320998) D2 D3 D12 +error(0.001338700097173320998) D2 D3 D12 D23 +error(0.001338700097173320998) D2 D3 D14 D23 +error(0.002673815958446297981) D2 D3 D23 +error(0.001338700097173320998) D2 D4 D5 +error(0.001338700097173320998) D2 D4 D5 D14 +error(0.001338700097173320998) D2 D4 D13 D23 +error(0.001338700097173320998) D2 D4 D14 D23 +error(0.002673815958446297981) D2 D4 D23 +error(0.0006697986788568588423) D2 D11 D12 D14 D18 D20 D21 +error(0.0006697986788568588423) D2 D11 D12 D14 D18 D23 +error(0.0006697986788568588423) D2 D11 D12 D18 +error(0.0006697986788568588423) D2 D11 D12 D18 D20 D21 +error(0.0006697986788568588423) D2 D11 D13 D14 D18 D20 D22 +error(0.0006697986788568588423) D2 D11 D13 D14 D18 D23 +error(0.0006697986788568588423) D2 D11 D13 D18 D19 +error(0.0006697986788568588423) D2 D11 D13 D18 D20 D22 +error(0.002006705456917235505) D2 D11 D18 +error(0.002006705456917235505) D2 D11 D18 D19 +error(0.001338700097173320998) D2 D11 D18 D20 D21 +error(0.001338700097173320998) D2 D11 D18 D20 D22 +error(0.004005357180252827609) D2 D11 D18 D23 +error(0.01322685654994845347) D2 D11 D20 +error(0.001338700097173320998) D2 D11 D21 +error(0.001338700097173320998) D2 D11 D21 D23 +error(0.001338700097173320998) D2 D11 D22 D23 +error(0.0006697986788568588423) D2 D12 D14 D18 D20 D21 +error(0.0006697986788568588423) D2 D12 D14 D18 D23 +error(0.0006697986788568588423) D2 D12 D18 +error(0.0006697986788568588423) D2 D12 D18 D20 D21 +error(0.001338700097173320998) D2 D12 D21 +error(0.001338700097173320998) D2 D12 D21 D23 +error(0.0006697986788568588423) D2 D13 D14 D18 D20 D22 +error(0.0006697986788568588423) D2 D13 D14 D18 D23 +error(0.0006697986788568588423) D2 D13 D18 D19 +error(0.0006697986788568588423) D2 D13 D18 D20 D22 +error(0.001338700097173320998) D2 D13 D22 D23 +error(0.002006705456917235505) D2 D18 +error(0.002006705456917235505) D2 D18 D19 +error(0.001338700097173320998) D2 D18 D20 D21 +error(0.001338700097173320998) D2 D18 D20 D22 +error(0.004005357180252827609) D2 D18 D23 +error(0.01322685654994845347) D2 D20 +error(0.002673815958446297981) D2 D21 +error(0.002673815958446297981) D2 D21 D23 +error(0.002673815958446297981) D2 D22 D23 +error(0.001338700097173320998) D3 D5 D7 +error(0.001338700097173320998) D3 D5 D7 D16 +error(0.001338700097173320998) D3 D5 D14 D25 +error(0.001338700097173320998) D3 D5 D16 D25 +error(0.002673815958446297981) D3 D5 D25 +error(0.001338700097173320998) D3 D7 +error(0.001338700097173320998) D3 D7 D16 +error(0.0006697986788568588423) D3 D12 D14 D16 D21 D23 +error(0.0006697986788568588423) D3 D12 D14 D16 D25 +error(0.0006697986788568588423) D3 D12 D14 D20 +error(0.0006697986788568588423) D3 D12 D14 D21 D23 +error(0.0006697986788568588423) D3 D12 D16 D21 +error(0.0006697986788568588423) D3 D12 D16 D25 +error(0.002006705456917235505) D3 D12 D20 +error(0.009953312530086681764) D3 D12 D21 +error(0.001338700097173320998) D3 D12 D21 D23 +error(0.001338700097173320998) D3 D12 D23 D25 +error(0.005333333333333313206) D3 D12 D25 +error(0.0006697986788568588423) D3 D14 D16 D21 D23 +error(0.0006697986788568588423) D3 D14 D16 D25 +error(0.0006697986788568588423) D3 D14 D20 +error(0.0006697986788568588423) D3 D14 D21 D23 +error(0.001338700097173320998) D3 D14 D23 D25 +error(0.0006697986788568588423) D3 D16 D21 +error(0.002006705456917235505) D3 D16 D25 +error(0.002006705456917235505) D3 D20 +error(0.009953312530086681764) D3 D21 +error(0.001338700097173320998) D3 D21 D23 +error(0.002673815958446297981) D3 D23 D25 +error(0.006657753962803452177) D3 D25 +error(0.001338700097173320998) D4 D5 D8 +error(0.001338700097173320998) D4 D5 D8 D17 +error(0.001338700097173320998) D4 D5 D14 D26 +error(0.001338700097173320998) D4 D5 D17 D26 +error(0.002673815958446297981) D4 D5 D26 +error(0.001338700097173320998) D4 D6 +error(0.001338700097173320998) D4 D6 D8 +error(0.001338700097173320998) D4 D6 D8 D17 +error(0.001338700097173320998) D4 D6 D15 +error(0.001338700097173320998) D4 D6 D15 D26 +error(0.001338700097173320998) D4 D6 D17 D26 +error(0.002673815958446297981) D4 D6 D26 +error(0.0006697986788568588423) D4 D13 D14 D17 D19 D22 D23 +error(0.0006697986788568588423) D4 D13 D14 D17 D19 D26 +error(0.0006697986788568588423) D4 D13 D14 D19 D20 +error(0.0006697986788568588423) D4 D13 D14 D19 D22 D23 +error(0.0006697986788568588423) D4 D13 D15 D17 D19 D22 D24 +error(0.0006697986788568588423) D4 D13 D15 D17 D19 D26 +error(0.0006697986788568588423) D4 D13 D15 D19 +error(0.0006697986788568588423) D4 D13 D15 D19 D22 D24 +error(0.002006705456917235505) D4 D13 D19 +error(0.002006705456917235505) D4 D13 D19 D20 +error(0.001338700097173320998) D4 D13 D19 D22 D23 +error(0.001338700097173320998) D4 D13 D19 D22 D24 +error(0.004005357180252827609) D4 D13 D19 D26 +error(0.01322685654994845347) D4 D13 D22 +error(0.001338700097173320998) D4 D13 D23 D26 +error(0.001338700097173320998) D4 D13 D24 +error(0.001338700097173320998) D4 D13 D24 D26 +error(0.0006697986788568588423) D4 D14 D17 D19 D22 D23 +error(0.0006697986788568588423) D4 D14 D17 D19 D26 +error(0.0006697986788568588423) D4 D14 D19 D20 +error(0.0006697986788568588423) D4 D14 D19 D22 D23 +error(0.001338700097173320998) D4 D14 D23 D26 +error(0.0006697986788568588423) D4 D15 D17 D19 D22 D24 +error(0.0006697986788568588423) D4 D15 D17 D19 D26 +error(0.0006697986788568588423) D4 D15 D19 +error(0.0006697986788568588423) D4 D15 D19 D22 D24 +error(0.001338700097173320998) D4 D15 D24 +error(0.001338700097173320998) D4 D15 D24 D26 +error(0.002006705456917235505) D4 D19 +error(0.002006705456917235505) D4 D19 D20 +error(0.001338700097173320998) D4 D19 D22 D23 +error(0.001338700097173320998) D4 D19 D22 D24 +error(0.004005357180252827609) D4 D19 D26 +error(0.01322685654994845347) D4 D22 +error(0.002673815958446297981) D4 D23 D26 +error(0.002673815958446297981) D4 D24 +error(0.002673815958446297981) D4 D24 D26 +error(0.001338700097173320998) D5 D7 D16 L0 +error(0.001338700097173320998) D5 D7 L0 +error(0.001338700097173320998) D5 D8 D17 L0 +error(0.001338700097173320998) D5 D8 L0 +error(0.0006697986788568588423) D5 D14 D16 D20 D21 +error(0.001338700097173320998) D5 D14 D16 D20 D23 D25 +error(0.0006697986788568588423) D5 D14 D16 D20 L0 +error(0.0006697986788568588423) D5 D14 D17 D20 D22 +error(0.001338700097173320998) D5 D14 D17 D20 D23 D26 +error(0.0006697986788568588423) D5 D14 D17 D20 L0 +error(0.002006705456917235505) D5 D14 D20 D21 +error(0.002006705456917235505) D5 D14 D20 D22 +error(0.001338700097173320998) D5 D14 D20 D23 D25 +error(0.001338700097173320998) D5 D14 D20 D23 D26 +error(0.004005357180252827609) D5 D14 D20 L0 +error(0.01322685654994845347) D5 D14 D23 +error(0.001338700097173320998) D5 D14 D25 L0 +error(0.001338700097173320998) D5 D14 D26 L0 +error(0.0006697986788568588423) D5 D16 D20 D21 +error(0.001338700097173320998) D5 D16 D20 D23 D25 +error(0.0006697986788568588423) D5 D16 D20 L0 +error(0.001338700097173320998) D5 D16 D25 L0 +error(0.0006697986788568588423) D5 D17 D20 D22 +error(0.001338700097173320998) D5 D17 D20 D23 D26 +error(0.0006697986788568588423) D5 D17 D20 L0 +error(0.001338700097173320998) D5 D17 D26 L0 +error(0.002006705456917235505) D5 D20 D21 +error(0.002006705456917235505) D5 D20 D22 +error(0.001338700097173320998) D5 D20 D23 D25 +error(0.001338700097173320998) D5 D20 D23 D26 +error(0.004005357180252827609) D5 D20 L0 +error(0.01322685654994845347) D5 D23 +error(0.002673815958446297981) D5 D25 L0 +error(0.002673815958446297981) D5 D26 L0 +error(0.001338700097173320998) D6 D8 D17 L0 +error(0.001338700097173320998) D6 D8 L0 +error(0.0006697986788568588423) D6 D15 D17 D22 +error(0.001338700097173320998) D6 D15 D17 D24 D26 +error(0.0006697986788568588423) D6 D15 D17 L0 +error(0.002006705456917235505) D6 D15 D22 +error(0.01060977777777773884) D6 D15 D24 +error(0.001338700097173320998) D6 D15 D24 D26 +error(0.001338700097173320998) D6 D15 D26 L0 +error(0.005995987492949031786) D6 D15 L0 +error(0.0006697986788568588423) D6 D17 D22 +error(0.001338700097173320998) D6 D17 D24 D26 +error(0.001338700097173320998) D6 D17 D26 L0 +error(0.0006697986788568588423) D6 D17 L0 +error(0.002006705456917235505) D6 D22 +error(0.01060977777777773884) D6 D24 +error(0.001338700097173320998) D6 D24 D26 +error(0.002673815958446297981) D6 D26 L0 +error(0.005995987492949031786) D6 L0 +error(0.002673815958446297981) D7 D16 D21 +error(0.002673815958446297981) D7 D16 D21 D23 +error(0.005333333333333313206) D7 D16 D21 D25 L0 +error(0.01060977777777773884) D7 D16 D25 +error(0.001338700097173320998) D7 D16 L0 +error(0.002673815958446297981) D7 D21 +error(0.002673815958446297981) D7 D21 D23 +error(0.005333333333333313206) D7 D21 D25 L0 +error(0.01060977777777773884) D7 D25 +error(0.001338700097173320998) D7 L0 +error(0.002673815958446297981) D8 D17 D22 D23 +error(0.002673815958446297981) D8 D17 D22 D24 +error(0.005333333333333313206) D8 D17 D22 D26 L0 +error(0.01060977777777773884) D8 D17 D26 +error(0.002673815958446297981) D8 D22 D23 +error(0.002673815958446297981) D8 D22 D24 +error(0.005333333333333313206) D8 D22 D26 L0 +error(0.01060977777777773884) D8 D26 +error(0.01518047719643240284) D9 +error(0.002673815958446297981) D9 D10 +error(0.003340032800510209492) D9 D10 D11 +error(0.001338700097173320998) D9 D10 D11 D18 D19 D20 +error(0.001338700097173320998) D9 D10 D11 D18 D19 D38 +error(0.0006697986788568588423) D9 D10 D11 D18 D36 +error(0.001338700097173320998) D9 D10 D11 D18 D37 D38 +error(0.0006697986788568588423) D9 D10 D11 D19 D37 +error(0.0006697986788568588423) D9 D10 D11 D20 D36 D37 +error(0.001338700097173320998) D9 D10 D11 D20 D38 +error(0.001338700097173320998) D9 D10 D11 D36 D37 D38 +error(0.0006697986788568588423) D9 D10 D13 D18 D19 D28 +error(0.0006697986788568588423) D9 D10 D13 D18 D19 D28 D38 +error(0.0006697986788568588423) D9 D10 D13 D18 D28 D37 +error(0.0006697986788568588423) D9 D10 D13 D18 D28 D37 D38 +error(0.001338700097173320998) D9 D10 D13 D19 D28 D37 +error(0.001338700097173320998) D9 D10 D13 D28 +error(0.001338700097173320998) D9 D10 D18 D19 +error(0.0006697986788568588423) D9 D10 D18 D36 +error(0.001338700097173320998) D9 D10 D18 D37 +error(0.0006697986788568588423) D9 D10 D19 D29 D36 +error(0.0006697986788568588423) D9 D10 D19 D29 D37 D38 +error(0.0006697986788568588423) D9 D10 D19 D36 +error(0.001338700097173320998) D9 D10 D19 D37 +error(0.0006697986788568588423) D9 D10 D20 D29 D36 D37 +error(0.0006697986788568588423) D9 D10 D20 D29 D38 +error(0.001338700097173320998) D9 D10 D29 +error(0.001338700097173320998) D9 D10 D29 D36 D37 D38 +error(0.001338700097173320998) D9 D10 D36 D37 +error(0.002673815958446297981) D9 D11 +error(0.001338700097173320998) D9 D11 D18 D20 +error(0.0006697986788568588423) D9 D11 D18 D27 +error(0.001338700097173320998) D9 D11 D18 D27 D36 +error(0.0006697986788568588423) D9 D11 D18 D27 D37 +error(0.0006697986788568588423) D9 D11 D18 D36 +error(0.001338700097173320998) D9 D11 D18 D38 +error(0.0006697986788568588423) D9 D11 D20 D36 +error(0.001338700097173320998) D9 D11 D20 D38 +error(0.001338700097173320998) D9 D11 D27 +error(0.0006697986788568588423) D9 D11 D27 D36 +error(0.0006697986788568588423) D9 D11 D27 D36 D37 +error(0.001338700097173320998) D9 D11 D36 D38 +error(0.0006697986788568588423) D9 D14 D18 D19 D20 D29 +error(0.0006697986788568588423) D9 D14 D18 D19 D29 D38 +error(0.0006697986788568588423) D9 D14 D18 D20 D29 +error(0.0006697986788568588423) D9 D14 D18 D29 D38 +error(0.004005357180252827609) D9 D14 D20 D29 D38 +error(0.004005357180252827609) D9 D14 D29 +error(0.004005357180252827609) D9 D18 +error(0.002006705456917235505) D9 D18 D19 +error(0.002006705456917235505) D9 D18 D19 D20 +error(0.002006705456917235505) D9 D18 D20 +error(0.001338700097173320998) D9 D18 D27 +error(0.002673815958446297981) D9 D18 D27 D36 +error(0.001338700097173320998) D9 D18 D27 D36 D37 +error(0.0006697986788568588423) D9 D18 D27 D37 D38 +error(0.004669790293214320931) D9 D18 D27 D38 +error(0.0006697986788568588423) D9 D18 D28 +error(0.0006697986788568588423) D9 D18 D28 D29 D36 D37 +error(0.0006697986788568588423) D9 D18 D28 D29 D38 +error(0.0006697986788568588423) D9 D18 D28 D36 D37 +error(0.0006697986788568588423) D9 D18 D29 D36 +error(0.0006697986788568588423) D9 D18 D29 D38 +error(0.001338700097173320998) D9 D18 D36 +error(0.0006697986788568588423) D9 D19 D28 D29 D36 +error(0.0006697986788568588423) D9 D19 D28 D29 D37 D38 +error(0.0006697986788568588423) D9 D19 D28 D36 +error(0.0006697986788568588423) D9 D19 D28 D37 +error(0.0006697986788568588423) D9 D20 D29 D36 +error(0.0006697986788568588423) D9 D20 D29 D38 +error(0.006657753962803452177) D9 D27 +error(0.0006697986788568588423) D9 D27 D36 +error(0.0006697986788568588423) D9 D27 D36 D37 +error(0.001338700097173320998) D9 D27 D36 D37 D38 +error(0.001338700097173320998) D9 D27 D36 D38 +error(0.001338700097173320998) D9 D28 +error(0.001338700097173320998) D9 D28 D29 +error(0.001338700097173320998) D9 D28 D29 D36 D37 D38 +error(0.001338700097173320998) D9 D28 D36 D37 +error(0.001338700097173320998) D9 D29 +error(0.001338700097173320998) D9 D29 D36 D38 +error(0.001338700097173320998) D9 D36 +error(0.01453014305882434701) D10 +error(0.001338700097173320998) D10 D11 +error(0.003340032800510209492) D10 D11 D13 +error(0.001338700097173320998) D10 D11 D13 D19 D20 D22 +error(0.001338700097173320998) D10 D11 D13 D19 D20 D40 +error(0.0006697986788568588423) D10 D11 D13 D19 D37 +error(0.001338700097173320998) D10 D11 D13 D19 D38 D40 +error(0.0006697986788568588423) D10 D11 D13 D20 D38 +error(0.0006697986788568588423) D10 D11 D13 D22 D37 D38 +error(0.001338700097173320998) D10 D11 D13 D22 D40 +error(0.001338700097173320998) D10 D11 D13 D37 D38 D40 +error(0.0006697986788568588423) D10 D11 D14 D18 D19 D20 D29 +error(0.0006697986788568588423) D10 D11 D14 D18 D19 D29 D38 +error(0.0006697986788568588423) D10 D11 D14 D19 D20 D29 D40 +error(0.0006697986788568588423) D10 D11 D14 D19 D29 D38 D40 +error(0.001338700097173320998) D10 D11 D14 D20 D29 D38 +error(0.001338700097173320998) D10 D11 D14 D29 +error(0.001338700097173320998) D10 D11 D18 D19 D20 +error(0.001338700097173320998) D10 D11 D18 D27 D36 +error(0.0006697986788568588423) D10 D11 D18 D27 D37 +error(0.0006697986788568588423) D10 D11 D18 D27 D37 D38 +error(0.0006697986788568588423) D10 D11 D20 D31 D36 D37 +error(0.0006697986788568588423) D10 D11 D20 D31 D36 D38 D40 +error(0.0006697986788568588423) D10 D11 D22 D31 D37 D38 +error(0.0006697986788568588423) D10 D11 D22 D31 D40 +error(0.001338700097173320998) D10 D11 D27 +error(0.0006697986788568588423) D10 D11 D27 D36 D37 +error(0.0006697986788568588423) D10 D11 D27 D36 D37 D38 +error(0.001338700097173320998) D10 D11 D31 +error(0.001338700097173320998) D10 D11 D31 D37 D38 D40 +error(0.002673815958446297981) D10 D13 +error(0.001338700097173320998) D10 D13 D19 D22 +error(0.0006697986788568588423) D10 D13 D19 D37 +error(0.001338700097173320998) D10 D13 D19 D40 +error(0.0006697986788568588423) D10 D13 D22 D37 +error(0.001338700097173320998) D10 D13 D22 D40 +error(0.001338700097173320998) D10 D13 D37 D40 +error(0.0006697986788568588423) D10 D17 D19 D20 D22 D31 +error(0.0006697986788568588423) D10 D17 D19 D20 D31 D40 +error(0.0006697986788568588423) D10 D17 D19 D22 D31 +error(0.0006697986788568588423) D10 D17 D19 D31 D40 +error(0.004005357180252827609) D10 D17 D22 D31 D40 +error(0.004005357180252827609) D10 D17 D31 +error(0.002006705456917235505) D10 D18 D19 +error(0.0006697986788568588423) D10 D18 D19 D20 +error(0.002006705456917235505) D10 D19 D20 D22 +error(0.002006705456917235505) D10 D19 D22 +error(0.001338700097173320998) D10 D19 D28 D36 +error(0.002673815958446297981) D10 D19 D28 D37 +error(0.001338700097173320998) D10 D19 D28 D37 D38 +error(0.0006697986788568588423) D10 D19 D28 D38 D40 +error(0.004669790293214320931) D10 D19 D28 D40 +error(0.0006697986788568588423) D10 D19 D29 D31 D37 D38 +error(0.0006697986788568588423) D10 D19 D29 D31 D40 +error(0.0006697986788568588423) D10 D19 D31 D37 +error(0.0006697986788568588423) D10 D19 D31 D40 +error(0.0006697986788568588423) D10 D20 D29 D31 D36 D37 +error(0.0006697986788568588423) D10 D20 D29 D31 D36 D38 D40 +error(0.0006697986788568588423) D10 D22 D31 D37 +error(0.0006697986788568588423) D10 D22 D31 D40 +error(0.006657753962803452177) D10 D28 +error(0.0006697986788568588423) D10 D28 D36 D37 +error(0.0006697986788568588423) D10 D28 D36 D37 D38 +error(0.001338700097173320998) D10 D28 D37 D38 D40 +error(0.001338700097173320998) D10 D28 D37 D40 +error(0.001338700097173320998) D10 D29 D31 +error(0.001338700097173320998) D10 D29 D31 D37 D38 D40 +error(0.001338700097173320998) D10 D31 +error(0.001338700097173320998) D10 D31 D37 D40 +error(0.01970848819953020456) D11 +error(0.002673815958446297981) D11 D12 +error(0.003340032800510209492) D11 D12 D14 +error(0.001338700097173320998) D11 D12 D14 D20 D21 D23 +error(0.001338700097173320998) D11 D12 D14 D20 D21 D41 +error(0.0006697986788568588423) D11 D12 D14 D20 D38 +error(0.001338700097173320998) D11 D12 D14 D20 D39 D41 +error(0.0006697986788568588423) D11 D12 D14 D21 D39 +error(0.0006697986788568588423) D11 D12 D14 D23 D38 D39 +error(0.001338700097173320998) D11 D12 D14 D23 D41 +error(0.001338700097173320998) D11 D12 D14 D38 D39 D41 +error(0.0006697986788568588423) D11 D12 D16 D20 D21 D30 +error(0.0006697986788568588423) D11 D12 D16 D20 D21 D30 D41 +error(0.0006697986788568588423) D11 D12 D16 D20 D30 D39 +error(0.0006697986788568588423) D11 D12 D16 D20 D30 D39 D41 +error(0.001338700097173320998) D11 D12 D16 D21 D30 D39 +error(0.001338700097173320998) D11 D12 D16 D30 +error(0.001338700097173320998) D11 D12 D20 D21 +error(0.0006697986788568588423) D11 D12 D20 D38 +error(0.001338700097173320998) D11 D12 D20 D39 +error(0.0006697986788568588423) D11 D12 D21 D32 D38 +error(0.0006697986788568588423) D11 D12 D21 D32 D39 D41 +error(0.0006697986788568588423) D11 D12 D21 D38 +error(0.001338700097173320998) D11 D12 D21 D39 +error(0.0006697986788568588423) D11 D12 D23 D32 D38 D39 +error(0.0006697986788568588423) D11 D12 D23 D32 D41 +error(0.001338700097173320998) D11 D12 D32 +error(0.001338700097173320998) D11 D12 D32 D38 D39 D41 +error(0.001338700097173320998) D11 D12 D38 D39 +error(0.001338700097173320998) D11 D13 +error(0.003340032800510209492) D11 D13 D14 +error(0.001338700097173320998) D11 D13 D14 D20 D22 D23 +error(0.001338700097173320998) D11 D13 D14 D20 D22 D41 +error(0.0006697986788568588423) D11 D13 D14 D20 D38 +error(0.001338700097173320998) D11 D13 D14 D20 D40 D41 +error(0.0006697986788568588423) D11 D13 D14 D22 D40 +error(0.0006697986788568588423) D11 D13 D14 D23 D38 D40 +error(0.001338700097173320998) D11 D13 D14 D23 D41 +error(0.001338700097173320998) D11 D13 D14 D38 D40 D41 +error(0.0006697986788568588423) D11 D13 D17 D19 D20 D22 D31 +error(0.0006697986788568588423) D11 D13 D17 D19 D20 D31 D40 +error(0.0006697986788568588423) D11 D13 D17 D20 D22 D31 D41 +error(0.0006697986788568588423) D11 D13 D17 D20 D31 D40 D41 +error(0.001338700097173320998) D11 D13 D17 D22 D31 D40 +error(0.001338700097173320998) D11 D13 D17 D31 +error(0.0006697986788568588423) D11 D13 D18 D19 D28 D38 +error(0.0006697986788568588423) D11 D13 D18 D28 D37 D38 +error(0.001338700097173320998) D11 D13 D19 D20 D22 +error(0.001338700097173320998) D11 D13 D19 D28 D37 +error(0.0006697986788568588423) D11 D13 D19 D28 D38 D40 +error(0.0006697986788568588423) D11 D13 D22 D32 D37 D38 +error(0.0006697986788568588423) D11 D13 D22 D32 D37 D40 D41 +error(0.0006697986788568588423) D11 D13 D23 D32 D38 D40 +error(0.0006697986788568588423) D11 D13 D23 D32 D41 +error(0.001338700097173320998) D11 D13 D28 +error(0.0006697986788568588423) D11 D13 D28 D37 D38 D40 +error(0.001338700097173320998) D11 D13 D32 +error(0.001338700097173320998) D11 D13 D32 D38 D40 D41 +error(0.0006697986788568588423) D11 D14 D18 D20 D29 +error(0.0006697986788568588423) D11 D14 D18 D29 D38 +error(0.001338700097173320998) D11 D14 D20 D29 D38 +error(0.0006697986788568588423) D11 D14 D20 D29 D39 +error(0.001338700097173320998) D11 D14 D29 +error(0.0006697986788568588423) D11 D14 D29 D38 D39 +error(0.002006705456917235505) D11 D18 D19 D20 +error(0.002006705456917235505) D11 D18 D20 +error(0.0006697986788568588423) D11 D18 D27 +error(0.004005357180252827609) D11 D18 D27 D36 +error(0.0006697986788568588423) D11 D18 D27 D38 +error(0.0006697986788568588423) D11 D19 D20 D22 +error(0.002006705456917235505) D11 D20 D21 +error(0.002006705456917235505) D11 D20 D21 D23 +error(0.0006697986788568588423) D11 D20 D21 D23 D32 +error(0.0006697986788568588423) D11 D20 D21 D32 D41 +error(0.002006705456917235505) D11 D20 D22 D23 +error(0.0006697986788568588423) D11 D20 D22 D23 D32 +error(0.0006697986788568588423) D11 D20 D22 D32 D41 +error(0.001338700097173320998) D11 D20 D29 D36 +error(0.001338700097173320998) D11 D20 D29 D36 D37 +error(0.001338700097173320998) D11 D20 D29 D36 D38 D39 +error(0.001338700097173320998) D11 D20 D29 D36 D38 D40 +error(0.004005357180252827609) D11 D20 D29 D36 D41 +error(0.002673815958446297981) D11 D20 D29 D38 +error(0.0006697986788568588423) D11 D20 D29 D39 D41 +error(0.0006697986788568588423) D11 D20 D29 D40 D41 +error(0.0006697986788568588423) D11 D20 D30 D32 D36 D38 D39 +error(0.0006697986788568588423) D11 D20 D30 D32 D36 D41 +error(0.0006697986788568588423) D11 D20 D30 D36 +error(0.0006697986788568588423) D11 D20 D30 D36 D38 D39 +error(0.0006697986788568588423) D11 D20 D31 D32 D36 D38 D40 +error(0.0006697986788568588423) D11 D20 D31 D32 D36 D41 +error(0.0006697986788568588423) D11 D21 D30 D32 D38 +error(0.0006697986788568588423) D11 D21 D30 D32 D39 D41 +error(0.0006697986788568588423) D11 D21 D30 D38 +error(0.0006697986788568588423) D11 D21 D30 D39 +error(0.0006697986788568588423) D11 D22 D31 D32 D37 D38 +error(0.0006697986788568588423) D11 D22 D31 D32 D37 D40 D41 +error(0.004005357180252827609) D11 D23 D32 D41 +error(0.004005357180252827609) D11 D27 +error(0.0006697986788568588423) D11 D27 D36 +error(0.0006697986788568588423) D11 D27 D36 D38 +error(0.007978628588222850399) D11 D29 +error(0.0006697986788568588423) D11 D29 D36 D37 D38 +error(0.0006697986788568588423) D11 D29 D36 D38 +error(0.0006697986788568588423) D11 D29 D37 D38 D40 +error(0.0006697986788568588423) D11 D29 D38 D39 +error(0.001338700097173320998) D11 D29 D38 D39 D41 +error(0.001338700097173320998) D11 D29 D38 D40 D41 +error(0.001338700097173320998) D11 D30 +error(0.001338700097173320998) D11 D30 D32 +error(0.001338700097173320998) D11 D30 D32 D38 D39 D41 +error(0.001338700097173320998) D11 D30 D38 D39 +error(0.001338700097173320998) D11 D31 D32 +error(0.001338700097173320998) D11 D31 D32 D38 D40 D41 +error(0.004005357180252827609) D11 D32 +error(0.01453014305882434701) D12 +error(0.001338700097173320998) D12 D14 +error(0.003340032800510209492) D12 D14 D16 +error(0.001338700097173320998) D12 D14 D16 D21 D23 D25 +error(0.001338700097173320998) D12 D14 D16 D21 D23 D43 +error(0.0006697986788568588423) D12 D14 D16 D21 D39 +error(0.001338700097173320998) D12 D14 D16 D21 D41 D43 +error(0.0006697986788568588423) D12 D14 D16 D23 D41 +error(0.0006697986788568588423) D12 D14 D16 D25 D39 D41 +error(0.001338700097173320998) D12 D14 D16 D25 D43 +error(0.001338700097173320998) D12 D14 D16 D39 D41 D43 +error(0.001338700097173320998) D12 D14 D20 D21 D23 +error(0.0006697986788568588423) D12 D14 D20 D21 D23 D32 +error(0.0006697986788568588423) D12 D14 D20 D21 D32 D41 +error(0.001338700097173320998) D12 D14 D20 D29 D38 +error(0.0006697986788568588423) D12 D14 D20 D29 D39 +error(0.0006697986788568588423) D12 D14 D20 D29 D39 D41 +error(0.0006697986788568588423) D12 D14 D21 D23 D32 D43 +error(0.0006697986788568588423) D12 D14 D21 D32 D41 D43 +error(0.001338700097173320998) D12 D14 D23 D32 D41 +error(0.0006697986788568588423) D12 D14 D23 D34 D38 D39 +error(0.0006697986788568588423) D12 D14 D23 D34 D38 D41 D43 +error(0.0006697986788568588423) D12 D14 D25 D34 D39 D41 +error(0.0006697986788568588423) D12 D14 D25 D34 D43 +error(0.001338700097173320998) D12 D14 D29 +error(0.0006697986788568588423) D12 D14 D29 D38 D39 +error(0.0006697986788568588423) D12 D14 D29 D38 D39 D41 +error(0.001338700097173320998) D12 D14 D32 +error(0.001338700097173320998) D12 D14 D34 +error(0.001338700097173320998) D12 D14 D34 D39 D41 D43 +error(0.002673815958446297981) D12 D16 +error(0.0006697986788568588423) D12 D16 D21 D23 D25 D34 +error(0.0006697986788568588423) D12 D16 D21 D23 D34 D43 +error(0.001338700097173320998) D12 D16 D21 D25 +error(0.0006697986788568588423) D12 D16 D21 D25 D34 +error(0.0006697986788568588423) D12 D16 D21 D34 D43 +error(0.0006697986788568588423) D12 D16 D21 D39 +error(0.001338700097173320998) D12 D16 D21 D43 +error(0.004005357180252827609) D12 D16 D25 D34 D43 +error(0.0006697986788568588423) D12 D16 D25 D39 +error(0.001338700097173320998) D12 D16 D25 D43 +error(0.004005357180252827609) D12 D16 D34 +error(0.001338700097173320998) D12 D16 D39 D43 +error(0.002006705456917235505) D12 D20 D21 +error(0.0006697986788568588423) D12 D20 D21 D23 +error(0.002006705456917235505) D12 D21 D23 D25 +error(0.002006705456917235505) D12 D21 D25 +error(0.001338700097173320998) D12 D21 D30 D38 +error(0.002673815958446297981) D12 D21 D30 D39 +error(0.001338700097173320998) D12 D21 D30 D39 D41 +error(0.0006697986788568588423) D12 D21 D30 D41 D43 +error(0.004669790293214320931) D12 D21 D30 D43 +error(0.0006697986788568588423) D12 D21 D32 D34 D39 D41 +error(0.0006697986788568588423) D12 D21 D32 D34 D43 +error(0.0006697986788568588423) D12 D21 D34 D39 +error(0.0006697986788568588423) D12 D21 D34 D43 +error(0.0006697986788568588423) D12 D23 D32 D34 D38 D39 +error(0.0006697986788568588423) D12 D23 D32 D34 D38 D41 D43 +error(0.0006697986788568588423) D12 D25 D34 D39 +error(0.0006697986788568588423) D12 D25 D34 D43 +error(0.006657753962803452177) D12 D30 +error(0.0006697986788568588423) D12 D30 D38 D39 +error(0.0006697986788568588423) D12 D30 D38 D39 D41 +error(0.001338700097173320998) D12 D30 D39 D41 D43 +error(0.001338700097173320998) D12 D30 D39 D43 +error(0.001338700097173320998) D12 D32 D34 +error(0.001338700097173320998) D12 D32 D34 D39 D41 D43 +error(0.001338700097173320998) D12 D34 +error(0.001338700097173320998) D12 D34 D39 D43 +error(0.01970848819953020456) D13 +error(0.001338700097173320998) D13 D14 +error(0.003340032800510209492) D13 D14 D17 +error(0.001338700097173320998) D13 D14 D17 D22 D23 D26 +error(0.001338700097173320998) D13 D14 D17 D22 D23 D44 +error(0.0006697986788568588423) D13 D14 D17 D22 D40 +error(0.001338700097173320998) D13 D14 D17 D22 D41 D44 +error(0.0006697986788568588423) D13 D14 D17 D23 D41 +error(0.0006697986788568588423) D13 D14 D17 D26 D40 D41 +error(0.001338700097173320998) D13 D14 D17 D26 D44 +error(0.001338700097173320998) D13 D14 D17 D40 D41 D44 +error(0.0006697986788568588423) D13 D14 D19 D20 D29 D40 +error(0.0006697986788568588423) D13 D14 D19 D29 D38 D40 +error(0.001338700097173320998) D13 D14 D20 D22 D23 +error(0.0006697986788568588423) D13 D14 D20 D22 D23 D32 +error(0.0006697986788568588423) D13 D14 D20 D22 D32 D41 +error(0.001338700097173320998) D13 D14 D20 D29 D38 +error(0.0006697986788568588423) D13 D14 D20 D29 D40 D41 +error(0.0006697986788568588423) D13 D14 D22 D23 D32 D44 +error(0.0006697986788568588423) D13 D14 D22 D32 D41 D44 +error(0.001338700097173320998) D13 D14 D23 D32 D41 +error(0.0006697986788568588423) D13 D14 D23 D35 D38 D40 +error(0.0006697986788568588423) D13 D14 D23 D35 D38 D41 D44 +error(0.0006697986788568588423) D13 D14 D26 D35 D40 D41 +error(0.0006697986788568588423) D13 D14 D26 D35 D44 +error(0.001338700097173320998) D13 D14 D29 +error(0.0006697986788568588423) D13 D14 D29 D38 D40 D41 +error(0.001338700097173320998) D13 D14 D32 +error(0.001338700097173320998) D13 D14 D35 +error(0.001338700097173320998) D13 D14 D35 D40 D41 D44 +error(0.002673815958446297981) D13 D15 +error(0.003340032800510209492) D13 D15 D17 +error(0.001338700097173320998) D13 D15 D17 D22 D24 D26 +error(0.001338700097173320998) D13 D15 D17 D22 D24 D44 +error(0.0006697986788568588423) D13 D15 D17 D22 D40 +error(0.001338700097173320998) D13 D15 D17 D22 D42 D44 +error(0.0006697986788568588423) D13 D15 D17 D24 D42 +error(0.0006697986788568588423) D13 D15 D17 D26 D40 D42 +error(0.001338700097173320998) D13 D15 D17 D26 D44 +error(0.001338700097173320998) D13 D15 D17 D40 D42 D44 +error(0.001338700097173320998) D13 D15 D22 D24 +error(0.0006697986788568588423) D13 D15 D22 D24 D33 +error(0.0006697986788568588423) D13 D15 D22 D24 D33 D44 +error(0.0006697986788568588423) D13 D15 D22 D33 D42 +error(0.0006697986788568588423) D13 D15 D22 D33 D42 D44 +error(0.0006697986788568588423) D13 D15 D22 D40 +error(0.001338700097173320998) D13 D15 D22 D42 +error(0.001338700097173320998) D13 D15 D24 D33 D42 +error(0.0006697986788568588423) D13 D15 D24 D35 D40 +error(0.0006697986788568588423) D13 D15 D24 D35 D42 D44 +error(0.0006697986788568588423) D13 D15 D24 D40 +error(0.001338700097173320998) D13 D15 D24 D42 +error(0.0006697986788568588423) D13 D15 D26 D35 D40 D42 +error(0.0006697986788568588423) D13 D15 D26 D35 D44 +error(0.001338700097173320998) D13 D15 D33 +error(0.001338700097173320998) D13 D15 D35 +error(0.001338700097173320998) D13 D15 D35 D40 D42 D44 +error(0.001338700097173320998) D13 D15 D40 D42 +error(0.0006697986788568588423) D13 D17 D19 D22 D31 +error(0.0006697986788568588423) D13 D17 D19 D31 D40 +error(0.0006697986788568588423) D13 D17 D22 D23 D26 D35 +error(0.0006697986788568588423) D13 D17 D22 D23 D35 D44 +error(0.0006697986788568588423) D13 D17 D22 D24 D26 D35 +error(0.0006697986788568588423) D13 D17 D22 D24 D35 D44 +error(0.001338700097173320998) D13 D17 D22 D31 D40 +error(0.0006697986788568588423) D13 D17 D22 D31 D42 +error(0.004005357180252827609) D13 D17 D26 D35 D44 +error(0.001338700097173320998) D13 D17 D31 +error(0.0006697986788568588423) D13 D17 D31 D40 D42 +error(0.004005357180252827609) D13 D17 D35 +error(0.0006697986788568588423) D13 D18 D19 D28 +error(0.0006697986788568588423) D13 D18 D28 D37 +error(0.002006705456917235505) D13 D19 D20 D22 +error(0.002006705456917235505) D13 D19 D22 +error(0.004005357180252827609) D13 D19 D28 D37 +error(0.0006697986788568588423) D13 D19 D28 D40 +error(0.0006697986788568588423) D13 D20 D22 D23 +error(0.002006705456917235505) D13 D22 D23 D26 +error(0.002006705456917235505) D13 D22 D24 +error(0.002006705456917235505) D13 D22 D24 D26 +error(0.001338700097173320998) D13 D22 D31 D37 +error(0.001338700097173320998) D13 D22 D31 D37 D38 +error(0.001338700097173320998) D13 D22 D31 D37 D40 D41 +error(0.001338700097173320998) D13 D22 D31 D37 D40 D42 +error(0.004005357180252827609) D13 D22 D31 D37 D44 +error(0.002673815958446297981) D13 D22 D31 D40 +error(0.0006697986788568588423) D13 D22 D31 D41 D44 +error(0.0006697986788568588423) D13 D22 D31 D42 D44 +error(0.0006697986788568588423) D13 D22 D32 D35 D37 D40 D41 +error(0.0006697986788568588423) D13 D22 D32 D35 D37 D44 +error(0.0006697986788568588423) D13 D22 D33 D35 D37 D40 D42 +error(0.0006697986788568588423) D13 D22 D33 D35 D37 D44 +error(0.0006697986788568588423) D13 D22 D33 D37 +error(0.0006697986788568588423) D13 D22 D33 D37 D40 D42 +error(0.0006697986788568588423) D13 D23 D32 D35 D38 D40 +error(0.0006697986788568588423) D13 D23 D32 D35 D38 D41 D44 +error(0.0006697986788568588423) D13 D24 D33 D35 D40 +error(0.0006697986788568588423) D13 D24 D33 D35 D42 D44 +error(0.0006697986788568588423) D13 D24 D33 D40 +error(0.0006697986788568588423) D13 D24 D33 D42 +error(0.004005357180252827609) D13 D28 +error(0.0006697986788568588423) D13 D28 D37 D40 +error(0.007978628588222850399) D13 D31 +error(0.0006697986788568588423) D13 D31 D37 D38 D40 +error(0.0006697986788568588423) D13 D31 D37 D40 +error(0.0006697986788568588423) D13 D31 D38 D40 D41 +error(0.001338700097173320998) D13 D31 D40 D41 D44 +error(0.0006697986788568588423) D13 D31 D40 D42 +error(0.001338700097173320998) D13 D31 D40 D42 D44 +error(0.001338700097173320998) D13 D32 D35 +error(0.001338700097173320998) D13 D32 D35 D40 D41 D44 +error(0.001338700097173320998) D13 D33 +error(0.001338700097173320998) D13 D33 D35 +error(0.001338700097173320998) D13 D33 D35 D40 D42 D44 +error(0.001338700097173320998) D13 D33 D40 D42 +error(0.01970848819953020456) D14 +error(0.004005357180252827609) D14 D16 +error(0.0006697986788568588423) D14 D16 D20 D21 D30 D41 +error(0.0006697986788568588423) D14 D16 D20 D30 D39 D41 +error(0.001338700097173320998) D14 D16 D21 D23 D25 +error(0.001338700097173320998) D14 D16 D21 D30 D39 +error(0.0006697986788568588423) D14 D16 D21 D30 D41 D43 +error(0.001338700097173320998) D14 D16 D23 D25 L0 +error(0.0006697986788568588423) D14 D16 D23 D41 +error(0.001338700097173320998) D14 D16 D23 D43 L0 +error(0.0006697986788568588423) D14 D16 D25 D39 D41 +error(0.0006697986788568588423) D14 D16 D25 D39 D43 L0 +error(0.0006697986788568588423) D14 D16 D25 D43 +error(0.001338700097173320998) D14 D16 D30 +error(0.0006697986788568588423) D14 D16 D30 D39 D41 D43 +error(0.001338700097173320998) D14 D16 D41 D43 L0 +error(0.004005357180252827609) D14 D17 +error(0.0006697986788568588423) D14 D17 D20 D22 D31 D41 +error(0.0006697986788568588423) D14 D17 D20 D31 D40 D41 +error(0.001338700097173320998) D14 D17 D22 D23 D26 +error(0.001338700097173320998) D14 D17 D22 D31 D40 +error(0.0006697986788568588423) D14 D17 D22 D31 D41 D44 +error(0.001338700097173320998) D14 D17 D23 D26 L0 +error(0.0006697986788568588423) D14 D17 D23 D41 +error(0.001338700097173320998) D14 D17 D23 D44 L0 +error(0.0006697986788568588423) D14 D17 D26 D40 D41 +error(0.0006697986788568588423) D14 D17 D26 D40 D44 L0 +error(0.0006697986788568588423) D14 D17 D26 D44 +error(0.001338700097173320998) D14 D17 D31 +error(0.0006697986788568588423) D14 D17 D31 D40 D41 D44 +error(0.001338700097173320998) D14 D17 D41 D44 L0 +error(0.002006705456917235505) D14 D20 D21 D23 +error(0.002006705456917235505) D14 D20 D22 D23 +error(0.0006697986788568588423) D14 D21 D23 D25 +error(0.0006697986788568588423) D14 D21 D23 D25 D34 +error(0.0006697986788568588423) D14 D21 D23 D34 D43 +error(0.0006697986788568588423) D14 D22 D23 D26 +error(0.0006697986788568588423) D14 D22 D23 D26 D35 +error(0.0006697986788568588423) D14 D22 D23 D35 D44 +error(0.0006697986788568588423) D14 D23 D25 D34 L0 +error(0.002006705456917235505) D14 D23 D25 L0 +error(0.0006697986788568588423) D14 D23 D26 D35 L0 +error(0.002006705456917235505) D14 D23 D26 L0 +error(0.001338700097173320998) D14 D23 D32 D38 D39 +error(0.001338700097173320998) D14 D23 D32 D38 D40 +error(0.001338700097173320998) D14 D23 D32 D38 D41 D43 +error(0.001338700097173320998) D14 D23 D32 D38 D41 D44 +error(0.004005357180252827609) D14 D23 D32 D38 L0 +error(0.002673815958446297981) D14 D23 D32 D41 +error(0.0006697986788568588423) D14 D23 D32 D43 L0 +error(0.0006697986788568588423) D14 D23 D32 D44 L0 +error(0.0006697986788568588423) D14 D23 D34 D38 D41 D43 +error(0.0006697986788568588423) D14 D23 D34 D38 L0 +error(0.0006697986788568588423) D14 D23 D34 D43 L0 +error(0.0006697986788568588423) D14 D23 D35 D38 D41 D44 +error(0.0006697986788568588423) D14 D23 D35 D38 L0 +error(0.0006697986788568588423) D14 D23 D35 D44 L0 +error(0.0006697986788568588423) D14 D25 D34 D39 D41 +error(0.0006697986788568588423) D14 D25 D34 D39 D43 L0 +error(0.001338700097173320998) D14 D25 D34 D43 +error(0.0006697986788568588423) D14 D26 D35 D40 D41 +error(0.0006697986788568588423) D14 D26 D35 D40 D44 L0 +error(0.001338700097173320998) D14 D26 D35 D44 +error(0.007978628588222850399) D14 D32 +error(0.0006697986788568588423) D14 D32 D38 D39 D41 +error(0.0006697986788568588423) D14 D32 D38 D40 D41 +error(0.0006697986788568588423) D14 D32 D39 D41 D43 +error(0.0006697986788568588423) D14 D32 D40 D41 D44 +error(0.001338700097173320998) D14 D32 D41 D43 L0 +error(0.001338700097173320998) D14 D32 D41 D44 L0 +error(0.002673815958446297981) D14 D34 +error(0.001338700097173320998) D14 D34 D41 D43 L0 +error(0.002673815958446297981) D14 D35 +error(0.001338700097173320998) D14 D35 D41 D44 L0 +error(0.01647853308100971984) D15 +error(0.004005357180252827609) D15 D17 +error(0.001338700097173320998) D15 D17 D22 D24 D26 +error(0.001338700097173320998) D15 D17 D22 D31 D40 +error(0.0006697986788568588423) D15 D17 D22 D31 D42 +error(0.0006697986788568588423) D15 D17 D22 D31 D42 D44 +error(0.001338700097173320998) D15 D17 D24 D26 L0 +error(0.0006697986788568588423) D15 D17 D24 D42 +error(0.001338700097173320998) D15 D17 D24 D44 L0 +error(0.0006697986788568588423) D15 D17 D26 D40 D42 +error(0.0006697986788568588423) D15 D17 D26 D40 D44 L0 +error(0.0006697986788568588423) D15 D17 D26 D44 +error(0.001338700097173320998) D15 D17 D31 +error(0.0006697986788568588423) D15 D17 D31 D40 D42 +error(0.0006697986788568588423) D15 D17 D31 D40 D42 D44 +error(0.001338700097173320998) D15 D17 D42 D44 L0 +error(0.002006705456917235505) D15 D22 D24 +error(0.0006697986788568588423) D15 D22 D24 D26 +error(0.0006697986788568588423) D15 D22 D24 D26 D35 +error(0.0006697986788568588423) D15 D22 D24 D35 D44 +error(0.0006697986788568588423) D15 D24 D26 D35 L0 +error(0.002006705456917235505) D15 D24 D26 L0 +error(0.001338700097173320998) D15 D24 D33 D40 +error(0.002673815958446297981) D15 D24 D33 D42 +error(0.001338700097173320998) D15 D24 D33 D42 D44 +error(0.0006697986788568588423) D15 D24 D33 D44 L0 +error(0.004669790293214320931) D15 D24 D33 L0 +error(0.0006697986788568588423) D15 D24 D35 D42 D44 +error(0.0006697986788568588423) D15 D24 D35 D44 L0 +error(0.0006697986788568588423) D15 D24 D35 L0 +error(0.001338700097173320998) D15 D24 D42 +error(0.004005357180252827609) D15 D24 L0 +error(0.0006697986788568588423) D15 D26 D35 D40 D42 +error(0.0006697986788568588423) D15 D26 D35 D40 D44 L0 +error(0.001338700097173320998) D15 D26 D35 D44 +error(0.006657753962803452177) D15 D33 +error(0.0006697986788568588423) D15 D33 D40 D42 +error(0.0006697986788568588423) D15 D33 D40 D42 D44 +error(0.001338700097173320998) D15 D33 D42 D44 L0 +error(0.001338700097173320998) D15 D33 D42 L0 +error(0.002673815958446297981) D15 D35 +error(0.001338700097173320998) D15 D35 D42 D44 L0 +error(0.001338700097173320998) D15 D42 L0 +error(0.01906422791000844316) D16 +error(0.0006697986788568588423) D16 D20 D21 D30 +error(0.0006697986788568588423) D16 D20 D30 D39 +error(0.002006705456917235505) D16 D21 D23 D25 +error(0.0006697986788568588423) D16 D21 D23 D32 D43 +error(0.002006705456917235505) D16 D21 D25 +error(0.004005357180252827609) D16 D21 D30 D39 +error(0.0006697986788568588423) D16 D21 D30 D43 +error(0.0006697986788568588423) D16 D21 D32 D41 D43 +error(0.0006697986788568588423) D16 D23 D25 D34 L0 +error(0.002006705456917235505) D16 D23 D25 L0 +error(0.001338700097173320998) D16 D23 D32 D41 +error(0.0006697986788568588423) D16 D23 D32 D43 L0 +error(0.0006697986788568588423) D16 D23 D34 D43 L0 +error(0.001338700097173320998) D16 D25 D34 D39 +error(0.001338700097173320998) D16 D25 D34 D39 D41 +error(0.004005357180252827609) D16 D25 D34 D39 D43 L0 +error(0.002673815958446297981) D16 D25 D34 D43 +error(0.0006697986788568588423) D16 D25 D34 L0 +error(0.0006697986788568588423) D16 D25 D39 +error(0.0006697986788568588423) D16 D25 D39 D43 L0 +error(0.0006697986788568588423) D16 D25 D43 +error(0.003340032800510209492) D16 D25 L0 +error(0.004005357180252827609) D16 D30 +error(0.0006697986788568588423) D16 D30 D39 D43 +error(0.001338700097173320998) D16 D32 +error(0.0006697986788568588423) D16 D32 D41 D43 L0 +error(0.006657753962803452177) D16 D34 +error(0.0006697986788568588423) D16 D34 D39 D41 D43 +error(0.0006697986788568588423) D16 D34 D39 D43 +error(0.0006697986788568588423) D16 D34 D41 D43 L0 +error(0.001338700097173320998) D16 D34 D43 L0 +error(0.001338700097173320998) D16 D43 L0 +error(0.01841910341341565158) D17 +error(0.002006705456917235505) D17 D22 D23 D26 +error(0.0006697986788568588423) D17 D22 D23 D32 D44 +error(0.002006705456917235505) D17 D22 D24 D26 +error(0.0006697986788568588423) D17 D22 D24 D33 D44 +error(0.0006697986788568588423) D17 D22 D32 D41 D44 +error(0.0006697986788568588423) D17 D22 D33 D42 D44 +error(0.0006697986788568588423) D17 D23 D26 D35 L0 +error(0.002006705456917235505) D17 D23 D26 L0 +error(0.001338700097173320998) D17 D23 D32 D41 +error(0.0006697986788568588423) D17 D23 D32 D44 L0 +error(0.0006697986788568588423) D17 D23 D35 D44 L0 +error(0.0006697986788568588423) D17 D24 D26 D35 L0 +error(0.002006705456917235505) D17 D24 D26 L0 +error(0.001338700097173320998) D17 D24 D33 D42 +error(0.0006697986788568588423) D17 D24 D33 D44 L0 +error(0.0006697986788568588423) D17 D24 D35 D44 L0 +error(0.001338700097173320998) D17 D26 D35 D40 D41 +error(0.001338700097173320998) D17 D26 D35 D40 D42 +error(0.004005357180252827609) D17 D26 D35 D40 D44 L0 +error(0.002673815958446297981) D17 D26 D35 D44 +error(0.001338700097173320998) D17 D32 +error(0.0006697986788568588423) D17 D32 D41 D44 L0 +error(0.001338700097173320998) D17 D33 +error(0.0006697986788568588423) D17 D33 D42 D44 L0 +error(0.006657753962803452177) D17 D35 +error(0.0006697986788568588423) D17 D35 D40 D41 D44 +error(0.0006697986788568588423) D17 D35 D40 D42 D44 +error(0.0006697986788568588423) D17 D35 D41 D44 L0 +error(0.0006697986788568588423) D17 D35 D42 D44 L0 +error(0.004669790293214320931) D18 +error(0.004005357180252827609) D18 D19 +error(0.004669790293214320931) D18 D19 D20 +error(0.001338700097173320998) D18 D19 D38 +error(0.004005357180252827609) D18 D20 +error(0.0006697986788568588423) D18 D27 +error(0.0006697986788568588423) D18 D27 D28 +error(0.0006697986788568588423) D18 D27 D28 D29 D36 D37 +error(0.0006697986788568588423) D18 D27 D28 D29 D38 +error(0.0006697986788568588423) D18 D27 D28 D36 D37 +error(0.0006697986788568588423) D18 D27 D29 D36 +error(0.0006697986788568588423) D18 D27 D29 D38 +error(0.0006697986788568588423) D18 D27 D36 +error(0.006657753962803452177) D18 D36 +error(0.001338700097173320998) D18 D36 D37 +error(0.001338700097173320998) D18 D37 +error(0.001338700097173320998) D18 D37 D38 +error(0.005333333333333313206) D18 D38 +error(0.004669790293214320931) D19 D20 D22 +error(0.001338700097173320998) D19 D20 D40 +error(0.004005357180252827609) D19 D22 +error(0.0006697986788568588423) D19 D28 D29 D31 D37 D38 +error(0.0006697986788568588423) D19 D28 D29 D31 D40 +error(0.0006697986788568588423) D19 D28 D31 D37 +error(0.0006697986788568588423) D19 D28 D31 D40 +error(0.001338700097173320998) D19 D36 +error(0.006657753962803452177) D19 D37 +error(0.001338700097173320998) D19 D37 D38 +error(0.001338700097173320998) D19 D38 D40 +error(0.005333333333333313206) D19 D40 +error(0.004005357180252827609) D20 D21 +error(0.004669790293214320931) D20 D21 D23 +error(0.001338700097173320998) D20 D21 D41 +error(0.004669790293214320931) D20 D22 D23 +error(0.001338700097173320998) D20 D22 D41 +error(0.0006697986788568588423) D20 D29 D30 D32 D36 D38 D39 +error(0.0006697986788568588423) D20 D29 D30 D32 D36 D41 +error(0.0006697986788568588423) D20 D29 D30 D36 +error(0.0006697986788568588423) D20 D29 D30 D36 D38 D39 +error(0.0006697986788568588423) D20 D29 D31 D32 D36 D38 D40 +error(0.0006697986788568588423) D20 D29 D31 D32 D36 D41 +error(0.001338700097173320998) D20 D36 +error(0.001338700097173320998) D20 D36 D37 +error(0.001338700097173320998) D20 D36 D38 D39 +error(0.001338700097173320998) D20 D36 D38 D40 +error(0.004005357180252827609) D20 D36 D41 +error(0.007978628588222850399) D20 D38 +error(0.001338700097173320998) D20 D39 +error(0.001338700097173320998) D20 D39 D41 +error(0.001338700097173320998) D20 D40 D41 +error(0.004669790293214320931) D21 D23 D25 +error(0.001338700097173320998) D21 D23 D43 +error(0.004005357180252827609) D21 D25 +error(0.0006697986788568588423) D21 D25 D34 +error(0.0006697986788568588423) D21 D30 D32 D34 D39 D41 +error(0.0006697986788568588423) D21 D30 D32 D34 D43 +error(0.0006697986788568588423) D21 D30 D34 D39 +error(0.0006697986788568588423) D21 D30 D34 D43 +error(0.0006697986788568588423) D21 D34 D43 +error(0.001338700097173320998) D21 D38 +error(0.006657753962803452177) D21 D39 +error(0.001338700097173320998) D21 D39 D41 +error(0.001338700097173320998) D21 D41 D43 +error(0.005333333333333313206) D21 D43 +error(0.004669790293214320931) D22 D23 D26 +error(0.001338700097173320998) D22 D23 D44 +error(0.004005357180252827609) D22 D24 +error(0.004669790293214320931) D22 D24 D26 +error(0.0006697986788568588423) D22 D24 D33 +error(0.001338700097173320998) D22 D24 D44 +error(0.0006697986788568588423) D22 D31 D32 D35 D37 D40 D41 +error(0.0006697986788568588423) D22 D31 D32 D35 D37 D44 +error(0.0006697986788568588423) D22 D31 D33 D35 D37 D40 D42 +error(0.0006697986788568588423) D22 D31 D33 D35 D37 D44 +error(0.0006697986788568588423) D22 D31 D33 D37 +error(0.0006697986788568588423) D22 D31 D33 D37 D40 D42 +error(0.0006697986788568588423) D22 D33 D42 +error(0.001338700097173320998) D22 D37 +error(0.001338700097173320998) D22 D37 D38 +error(0.001338700097173320998) D22 D37 D40 D41 +error(0.001338700097173320998) D22 D37 D40 D42 +error(0.004005357180252827609) D22 D37 D44 +error(0.007978628588222850399) D22 D40 +error(0.001338700097173320998) D22 D41 D44 +error(0.001338700097173320998) D22 D42 +error(0.001338700097173320998) D22 D42 D44 +error(0.004005357180252827609) D23 D25 L0 +error(0.004005357180252827609) D23 D26 L0 +error(0.0006697986788568588423) D23 D32 D34 D38 D41 D43 +error(0.0006697986788568588423) D23 D32 D34 D38 L0 +error(0.0006697986788568588423) D23 D32 D35 D38 D41 D44 +error(0.0006697986788568588423) D23 D32 D35 D38 L0 +error(0.001338700097173320998) D23 D38 D39 +error(0.001338700097173320998) D23 D38 D40 +error(0.001338700097173320998) D23 D38 D41 D43 +error(0.001338700097173320998) D23 D38 D41 D44 +error(0.004005357180252827609) D23 D38 L0 +error(0.007978628588222850399) D23 D41 +error(0.001338700097173320998) D23 D43 L0 +error(0.001338700097173320998) D23 D44 L0 +error(0.004005357180252827609) D24 D26 L0 +error(0.0006697986788568588423) D24 D33 D35 D42 D44 +error(0.0006697986788568588423) D24 D33 D35 L0 +error(0.004669790293214320931) D24 D33 D42 +error(0.001338700097173320998) D24 D33 L0 +error(0.001338700097173320998) D24 D40 +error(0.006657753962803452177) D24 D42 +error(0.001338700097173320998) D24 D42 D44 +error(0.001338700097173320998) D24 D44 L0 +error(0.007318633932043431753) D24 L0 +error(0.0006697986788568588423) D25 D34 D39 +error(0.0006697986788568588423) D25 D34 D39 D43 L0 +error(0.001338700097173320998) D25 D34 D43 +error(0.0006697986788568588423) D25 D34 L0 +error(0.001338700097173320998) D25 D39 +error(0.001338700097173320998) D25 D39 D41 +error(0.004005357180252827609) D25 D39 D43 L0 +error(0.006657753962803452177) D25 D43 +error(0.003340032800510209492) D25 L0 +error(0.001338700097173320998) D26 D40 D41 +error(0.001338700097173320998) D26 D40 D42 +error(0.004005357180252827609) D26 D40 D44 L0 +error(0.006657753962803452177) D26 D44 +error(0.002006705456917235505) D27 +error(0.002673815958446297981) D27 D28 +error(0.003340032800510209492) D27 D28 D29 +error(0.001338700097173320998) D27 D28 D29 D36 D37 D38 +error(0.001338700097173320998) D27 D28 D29 D36 D37 D56 +error(0.0006697986788568588423) D27 D28 D29 D36 D54 +error(0.001338700097173320998) D27 D28 D29 D36 D55 D56 +error(0.0006697986788568588423) D27 D28 D29 D37 D55 +error(0.0006697986788568588423) D27 D28 D29 D38 D54 D55 +error(0.001338700097173320998) D27 D28 D29 D38 D56 +error(0.001338700097173320998) D27 D28 D29 D54 D55 D56 +error(0.0006697986788568588423) D27 D28 D31 D36 D37 D46 +error(0.0006697986788568588423) D27 D28 D31 D36 D37 D46 D56 +error(0.0006697986788568588423) D27 D28 D31 D36 D46 D55 +error(0.0006697986788568588423) D27 D28 D31 D36 D46 D55 D56 +error(0.001338700097173320998) D27 D28 D31 D37 D46 D55 +error(0.001338700097173320998) D27 D28 D31 D46 +error(0.001338700097173320998) D27 D28 D36 D37 +error(0.0006697986788568588423) D27 D28 D36 D54 +error(0.001338700097173320998) D27 D28 D36 D55 +error(0.0006697986788568588423) D27 D28 D37 D47 D54 +error(0.0006697986788568588423) D27 D28 D37 D47 D55 D56 +error(0.0006697986788568588423) D27 D28 D37 D54 +error(0.001338700097173320998) D27 D28 D37 D55 +error(0.0006697986788568588423) D27 D28 D38 D47 D54 D55 +error(0.0006697986788568588423) D27 D28 D38 D47 D56 +error(0.001338700097173320998) D27 D28 D47 +error(0.001338700097173320998) D27 D28 D47 D54 D55 D56 +error(0.001338700097173320998) D27 D28 D54 D55 +error(0.002673815958446297981) D27 D29 +error(0.001338700097173320998) D27 D29 D36 D38 +error(0.0006697986788568588423) D27 D29 D36 D45 +error(0.001338700097173320998) D27 D29 D36 D45 D54 +error(0.0006697986788568588423) D27 D29 D36 D45 D55 +error(0.0006697986788568588423) D27 D29 D36 D54 +error(0.001338700097173320998) D27 D29 D36 D56 +error(0.0006697986788568588423) D27 D29 D38 D54 +error(0.001338700097173320998) D27 D29 D38 D56 +error(0.001338700097173320998) D27 D29 D45 +error(0.0006697986788568588423) D27 D29 D45 D54 +error(0.0006697986788568588423) D27 D29 D45 D54 D55 +error(0.001338700097173320998) D27 D29 D54 D56 +error(0.0006697986788568588423) D27 D32 D36 D37 D38 D47 +error(0.0006697986788568588423) D27 D32 D36 D37 D47 D56 +error(0.0006697986788568588423) D27 D32 D36 D38 D47 +error(0.0006697986788568588423) D27 D32 D36 D47 D56 +error(0.004005357180252827609) D27 D32 D38 D47 D56 +error(0.004005357180252827609) D27 D32 D47 +error(0.002006705456917235505) D27 D36 +error(0.001338700097173320998) D27 D36 D45 +error(0.002673815958446297981) D27 D36 D45 D54 +error(0.001338700097173320998) D27 D36 D45 D54 D55 +error(0.0006697986788568588423) D27 D36 D45 D55 D56 +error(0.004669790293214320931) D27 D36 D45 D56 +error(0.0006697986788568588423) D27 D36 D46 +error(0.0006697986788568588423) D27 D36 D46 D47 D54 D55 +error(0.0006697986788568588423) D27 D36 D46 D47 D56 +error(0.0006697986788568588423) D27 D36 D46 D54 D55 +error(0.0006697986788568588423) D27 D36 D47 D54 +error(0.0006697986788568588423) D27 D36 D47 D56 +error(0.001338700097173320998) D27 D36 D54 +error(0.0006697986788568588423) D27 D37 D46 D47 D54 +error(0.0006697986788568588423) D27 D37 D46 D47 D55 D56 +error(0.0006697986788568588423) D27 D37 D46 D54 +error(0.0006697986788568588423) D27 D37 D46 D55 +error(0.0006697986788568588423) D27 D38 D47 D54 +error(0.0006697986788568588423) D27 D38 D47 D56 +error(0.006657753962803452177) D27 D45 +error(0.0006697986788568588423) D27 D45 D54 +error(0.0006697986788568588423) D27 D45 D54 D55 +error(0.001338700097173320998) D27 D45 D54 D55 D56 +error(0.001338700097173320998) D27 D45 D54 D56 +error(0.001338700097173320998) D27 D46 +error(0.001338700097173320998) D27 D46 D47 +error(0.001338700097173320998) D27 D46 D47 D54 D55 D56 +error(0.001338700097173320998) D27 D46 D54 D55 +error(0.001338700097173320998) D27 D47 +error(0.001338700097173320998) D27 D47 D54 D56 +error(0.001338700097173320998) D27 D54 +error(0.003340032800510209492) D28 D29 D31 +error(0.001338700097173320998) D28 D29 D31 D37 D38 D40 +error(0.001338700097173320998) D28 D29 D31 D37 D38 D58 +error(0.0006697986788568588423) D28 D29 D31 D37 D55 +error(0.001338700097173320998) D28 D29 D31 D37 D56 D58 +error(0.0006697986788568588423) D28 D29 D31 D38 D56 +error(0.0006697986788568588423) D28 D29 D31 D40 D55 D56 +error(0.001338700097173320998) D28 D29 D31 D40 D58 +error(0.001338700097173320998) D28 D29 D31 D55 D56 D58 +error(0.0006697986788568588423) D28 D29 D32 D36 D37 D38 D47 +error(0.0006697986788568588423) D28 D29 D32 D36 D37 D47 D56 +error(0.0006697986788568588423) D28 D29 D32 D37 D38 D47 D58 +error(0.0006697986788568588423) D28 D29 D32 D37 D47 D56 D58 +error(0.001338700097173320998) D28 D29 D32 D38 D47 D56 +error(0.001338700097173320998) D28 D29 D32 D47 +error(0.001338700097173320998) D28 D29 D36 D45 D54 +error(0.0006697986788568588423) D28 D29 D36 D45 D55 +error(0.0006697986788568588423) D28 D29 D36 D45 D55 D56 +error(0.0006697986788568588423) D28 D29 D38 D49 D54 D55 +error(0.0006697986788568588423) D28 D29 D38 D49 D54 D56 D58 +error(0.0006697986788568588423) D28 D29 D40 D49 D55 D56 +error(0.0006697986788568588423) D28 D29 D40 D49 D58 +error(0.001338700097173320998) D28 D29 D45 +error(0.0006697986788568588423) D28 D29 D45 D54 D55 +error(0.0006697986788568588423) D28 D29 D45 D54 D55 D56 +error(0.001338700097173320998) D28 D29 D49 +error(0.001338700097173320998) D28 D29 D49 D55 D56 D58 +error(0.002673815958446297981) D28 D31 +error(0.001338700097173320998) D28 D31 D37 D40 +error(0.0006697986788568588423) D28 D31 D37 D55 +error(0.001338700097173320998) D28 D31 D37 D58 +error(0.0006697986788568588423) D28 D31 D40 D55 +error(0.001338700097173320998) D28 D31 D40 D58 +error(0.001338700097173320998) D28 D31 D55 D58 +error(0.0006697986788568588423) D28 D35 D37 D38 D40 D49 +error(0.0006697986788568588423) D28 D35 D37 D38 D49 D58 +error(0.0006697986788568588423) D28 D35 D37 D40 D49 +error(0.0006697986788568588423) D28 D35 D37 D49 D58 +error(0.004005357180252827609) D28 D35 D40 D49 D58 +error(0.004005357180252827609) D28 D35 D49 +error(0.001338700097173320998) D28 D37 D46 D54 +error(0.002673815958446297981) D28 D37 D46 D55 +error(0.001338700097173320998) D28 D37 D46 D55 D56 +error(0.0006697986788568588423) D28 D37 D46 D56 D58 +error(0.004669790293214320931) D28 D37 D46 D58 +error(0.0006697986788568588423) D28 D37 D47 D49 D55 D56 +error(0.0006697986788568588423) D28 D37 D47 D49 D58 +error(0.0006697986788568588423) D28 D37 D49 D55 +error(0.0006697986788568588423) D28 D37 D49 D58 +error(0.0006697986788568588423) D28 D38 D47 D49 D54 D55 +error(0.0006697986788568588423) D28 D38 D47 D49 D54 D56 D58 +error(0.0006697986788568588423) D28 D40 D49 D55 +error(0.0006697986788568588423) D28 D40 D49 D58 +error(0.006657753962803452177) D28 D46 +error(0.0006697986788568588423) D28 D46 D54 D55 +error(0.0006697986788568588423) D28 D46 D54 D55 D56 +error(0.001338700097173320998) D28 D46 D55 D56 D58 +error(0.001338700097173320998) D28 D46 D55 D58 +error(0.001338700097173320998) D28 D47 D49 +error(0.001338700097173320998) D28 D47 D49 D55 D56 D58 +error(0.001338700097173320998) D28 D49 +error(0.001338700097173320998) D28 D49 D55 D58 +error(0.002673815958446297981) D29 D30 +error(0.003340032800510209492) D29 D30 D32 +error(0.001338700097173320998) D29 D30 D32 D38 D39 D41 +error(0.001338700097173320998) D29 D30 D32 D38 D39 D59 +error(0.0006697986788568588423) D29 D30 D32 D38 D56 +error(0.001338700097173320998) D29 D30 D32 D38 D57 D59 +error(0.0006697986788568588423) D29 D30 D32 D39 D57 +error(0.0006697986788568588423) D29 D30 D32 D41 D56 D57 +error(0.001338700097173320998) D29 D30 D32 D41 D59 +error(0.001338700097173320998) D29 D30 D32 D56 D57 D59 +error(0.0006697986788568588423) D29 D30 D34 D38 D39 D48 +error(0.0006697986788568588423) D29 D30 D34 D38 D39 D48 D59 +error(0.0006697986788568588423) D29 D30 D34 D38 D48 D57 +error(0.0006697986788568588423) D29 D30 D34 D38 D48 D57 D59 +error(0.001338700097173320998) D29 D30 D34 D39 D48 D57 +error(0.001338700097173320998) D29 D30 D34 D48 +error(0.001338700097173320998) D29 D30 D38 D39 +error(0.0006697986788568588423) D29 D30 D38 D56 +error(0.001338700097173320998) D29 D30 D38 D57 +error(0.0006697986788568588423) D29 D30 D39 D50 D56 +error(0.0006697986788568588423) D29 D30 D39 D50 D57 D59 +error(0.0006697986788568588423) D29 D30 D39 D56 +error(0.001338700097173320998) D29 D30 D39 D57 +error(0.0006697986788568588423) D29 D30 D41 D50 D56 D57 +error(0.0006697986788568588423) D29 D30 D41 D50 D59 +error(0.001338700097173320998) D29 D30 D50 +error(0.001338700097173320998) D29 D30 D50 D56 D57 D59 +error(0.001338700097173320998) D29 D30 D56 D57 +error(0.003340032800510209492) D29 D31 D32 +error(0.001338700097173320998) D29 D31 D32 D38 D40 D41 +error(0.001338700097173320998) D29 D31 D32 D38 D40 D59 +error(0.0006697986788568588423) D29 D31 D32 D38 D56 +error(0.001338700097173320998) D29 D31 D32 D38 D58 D59 +error(0.0006697986788568588423) D29 D31 D32 D40 D58 +error(0.0006697986788568588423) D29 D31 D32 D41 D56 D58 +error(0.001338700097173320998) D29 D31 D32 D41 D59 +error(0.001338700097173320998) D29 D31 D32 D56 D58 D59 +error(0.0006697986788568588423) D29 D31 D35 D37 D38 D40 D49 +error(0.0006697986788568588423) D29 D31 D35 D37 D38 D49 D58 +error(0.0006697986788568588423) D29 D31 D35 D38 D40 D49 D59 +error(0.0006697986788568588423) D29 D31 D35 D38 D49 D58 D59 +error(0.001338700097173320998) D29 D31 D35 D40 D49 D58 +error(0.001338700097173320998) D29 D31 D35 D49 +error(0.0006697986788568588423) D29 D31 D36 D37 D46 D56 +error(0.0006697986788568588423) D29 D31 D36 D46 D55 D56 +error(0.001338700097173320998) D29 D31 D37 D46 D55 +error(0.0006697986788568588423) D29 D31 D37 D46 D56 D58 +error(0.0006697986788568588423) D29 D31 D40 D50 D55 D56 +error(0.0006697986788568588423) D29 D31 D40 D50 D55 D58 D59 +error(0.0006697986788568588423) D29 D31 D41 D50 D56 D58 +error(0.0006697986788568588423) D29 D31 D41 D50 D59 +error(0.001338700097173320998) D29 D31 D46 +error(0.0006697986788568588423) D29 D31 D46 D55 D56 D58 +error(0.001338700097173320998) D29 D31 D50 +error(0.001338700097173320998) D29 D31 D50 D56 D58 D59 +error(0.0006697986788568588423) D29 D32 D36 D38 D47 +error(0.0006697986788568588423) D29 D32 D36 D47 D56 +error(0.001338700097173320998) D29 D32 D38 D47 D56 +error(0.0006697986788568588423) D29 D32 D38 D47 D57 +error(0.001338700097173320998) D29 D32 D47 +error(0.0006697986788568588423) D29 D32 D47 D56 D57 +error(0.0006697986788568588423) D29 D36 D45 +error(0.004005357180252827609) D29 D36 D45 D54 +error(0.0006697986788568588423) D29 D36 D45 D56 +error(0.0006697986788568588423) D29 D38 D39 D41 D50 +error(0.0006697986788568588423) D29 D38 D39 D50 D59 +error(0.0006697986788568588423) D29 D38 D40 D41 D50 +error(0.0006697986788568588423) D29 D38 D40 D50 D59 +error(0.001338700097173320998) D29 D38 D47 D54 +error(0.001338700097173320998) D29 D38 D47 D54 D55 +error(0.001338700097173320998) D29 D38 D47 D54 D56 D57 +error(0.001338700097173320998) D29 D38 D47 D54 D56 D58 +error(0.004005357180252827609) D29 D38 D47 D54 D59 +error(0.002673815958446297981) D29 D38 D47 D56 +error(0.0006697986788568588423) D29 D38 D47 D57 D59 +error(0.0006697986788568588423) D29 D38 D47 D58 D59 +error(0.0006697986788568588423) D29 D38 D48 D50 D54 D56 D57 +error(0.0006697986788568588423) D29 D38 D48 D50 D54 D59 +error(0.0006697986788568588423) D29 D38 D48 D54 +error(0.0006697986788568588423) D29 D38 D48 D54 D56 D57 +error(0.0006697986788568588423) D29 D38 D49 D50 D54 D56 D58 +error(0.0006697986788568588423) D29 D38 D49 D50 D54 D59 +error(0.0006697986788568588423) D29 D39 D48 D50 D56 +error(0.0006697986788568588423) D29 D39 D48 D50 D57 D59 +error(0.0006697986788568588423) D29 D39 D48 D56 +error(0.0006697986788568588423) D29 D39 D48 D57 +error(0.0006697986788568588423) D29 D40 D49 D50 D55 D56 +error(0.0006697986788568588423) D29 D40 D49 D50 D55 D58 D59 +error(0.004005357180252827609) D29 D41 D50 D59 +error(0.004005357180252827609) D29 D45 +error(0.0006697986788568588423) D29 D45 D54 +error(0.0006697986788568588423) D29 D45 D54 D56 +error(0.007978628588222850399) D29 D47 +error(0.0006697986788568588423) D29 D47 D54 D55 D56 +error(0.0006697986788568588423) D29 D47 D54 D56 +error(0.0006697986788568588423) D29 D47 D55 D56 D58 +error(0.0006697986788568588423) D29 D47 D56 D57 +error(0.001338700097173320998) D29 D47 D56 D57 D59 +error(0.001338700097173320998) D29 D47 D56 D58 D59 +error(0.001338700097173320998) D29 D48 +error(0.001338700097173320998) D29 D48 D50 +error(0.001338700097173320998) D29 D48 D50 D56 D57 D59 +error(0.001338700097173320998) D29 D48 D56 D57 +error(0.001338700097173320998) D29 D49 D50 +error(0.001338700097173320998) D29 D49 D50 D56 D58 D59 +error(0.004005357180252827609) D29 D50 +error(0.003340032800510209492) D30 D32 D34 +error(0.001338700097173320998) D30 D32 D34 D39 D41 D43 +error(0.001338700097173320998) D30 D32 D34 D39 D41 D61 +error(0.0006697986788568588423) D30 D32 D34 D39 D57 +error(0.001338700097173320998) D30 D32 D34 D39 D59 D61 +error(0.0006697986788568588423) D30 D32 D34 D41 D59 +error(0.0006697986788568588423) D30 D32 D34 D43 D57 D59 +error(0.001338700097173320998) D30 D32 D34 D43 D61 +error(0.001338700097173320998) D30 D32 D34 D57 D59 D61 +error(0.0006697986788568588423) D30 D32 D38 D39 D41 D50 +error(0.0006697986788568588423) D30 D32 D38 D39 D50 D59 +error(0.001338700097173320998) D30 D32 D38 D47 D56 +error(0.0006697986788568588423) D30 D32 D38 D47 D57 +error(0.0006697986788568588423) D30 D32 D38 D47 D57 D59 +error(0.0006697986788568588423) D30 D32 D39 D41 D50 D61 +error(0.0006697986788568588423) D30 D32 D39 D50 D59 D61 +error(0.001338700097173320998) D30 D32 D41 D50 D59 +error(0.0006697986788568588423) D30 D32 D41 D52 D56 D57 +error(0.0006697986788568588423) D30 D32 D41 D52 D56 D59 D61 +error(0.0006697986788568588423) D30 D32 D43 D52 D57 D59 +error(0.0006697986788568588423) D30 D32 D43 D52 D61 +error(0.001338700097173320998) D30 D32 D47 +error(0.0006697986788568588423) D30 D32 D47 D56 D57 +error(0.0006697986788568588423) D30 D32 D47 D56 D57 D59 +error(0.001338700097173320998) D30 D32 D50 +error(0.001338700097173320998) D30 D32 D52 +error(0.001338700097173320998) D30 D32 D52 D57 D59 D61 +error(0.002673815958446297981) D30 D34 +error(0.0006697986788568588423) D30 D34 D39 D41 D43 D52 +error(0.0006697986788568588423) D30 D34 D39 D41 D52 D61 +error(0.001338700097173320998) D30 D34 D39 D43 +error(0.0006697986788568588423) D30 D34 D39 D43 D52 +error(0.0006697986788568588423) D30 D34 D39 D52 D61 +error(0.0006697986788568588423) D30 D34 D39 D57 +error(0.001338700097173320998) D30 D34 D39 D61 +error(0.004005357180252827609) D30 D34 D43 D52 D61 +error(0.0006697986788568588423) D30 D34 D43 D57 +error(0.001338700097173320998) D30 D34 D43 D61 +error(0.004005357180252827609) D30 D34 D52 +error(0.001338700097173320998) D30 D34 D57 D61 +error(0.001338700097173320998) D30 D39 D48 D56 +error(0.002673815958446297981) D30 D39 D48 D57 +error(0.001338700097173320998) D30 D39 D48 D57 D59 +error(0.0006697986788568588423) D30 D39 D48 D59 D61 +error(0.004669790293214320931) D30 D39 D48 D61 +error(0.0006697986788568588423) D30 D39 D50 D52 D57 D59 +error(0.0006697986788568588423) D30 D39 D50 D52 D61 +error(0.0006697986788568588423) D30 D39 D52 D57 +error(0.0006697986788568588423) D30 D39 D52 D61 +error(0.0006697986788568588423) D30 D41 D50 D52 D56 D57 +error(0.0006697986788568588423) D30 D41 D50 D52 D56 D59 D61 +error(0.0006697986788568588423) D30 D43 D52 D57 +error(0.0006697986788568588423) D30 D43 D52 D61 +error(0.006657753962803452177) D30 D48 +error(0.0006697986788568588423) D30 D48 D56 D57 +error(0.0006697986788568588423) D30 D48 D56 D57 D59 +error(0.001338700097173320998) D30 D48 D57 D59 D61 +error(0.001338700097173320998) D30 D48 D57 D61 +error(0.001338700097173320998) D30 D50 D52 +error(0.001338700097173320998) D30 D50 D52 D57 D59 D61 +error(0.001338700097173320998) D30 D52 +error(0.001338700097173320998) D30 D52 D57 D61 +error(0.003340032800510209492) D31 D32 D35 +error(0.001338700097173320998) D31 D32 D35 D40 D41 D44 +error(0.001338700097173320998) D31 D32 D35 D40 D41 D62 +error(0.0006697986788568588423) D31 D32 D35 D40 D58 +error(0.001338700097173320998) D31 D32 D35 D40 D59 D62 +error(0.0006697986788568588423) D31 D32 D35 D41 D59 +error(0.0006697986788568588423) D31 D32 D35 D44 D58 D59 +error(0.001338700097173320998) D31 D32 D35 D44 D62 +error(0.001338700097173320998) D31 D32 D35 D58 D59 D62 +error(0.0006697986788568588423) D31 D32 D37 D38 D47 D58 +error(0.0006697986788568588423) D31 D32 D37 D47 D56 D58 +error(0.0006697986788568588423) D31 D32 D38 D40 D41 D50 +error(0.0006697986788568588423) D31 D32 D38 D40 D50 D59 +error(0.001338700097173320998) D31 D32 D38 D47 D56 +error(0.0006697986788568588423) D31 D32 D38 D47 D58 D59 +error(0.0006697986788568588423) D31 D32 D40 D41 D50 D62 +error(0.0006697986788568588423) D31 D32 D40 D50 D59 D62 +error(0.001338700097173320998) D31 D32 D41 D50 D59 +error(0.0006697986788568588423) D31 D32 D41 D53 D56 D58 +error(0.0006697986788568588423) D31 D32 D41 D53 D56 D59 D62 +error(0.0006697986788568588423) D31 D32 D44 D53 D58 D59 +error(0.0006697986788568588423) D31 D32 D44 D53 D62 +error(0.001338700097173320998) D31 D32 D47 +error(0.0006697986788568588423) D31 D32 D47 D56 D58 D59 +error(0.001338700097173320998) D31 D32 D50 +error(0.001338700097173320998) D31 D32 D53 +error(0.001338700097173320998) D31 D32 D53 D58 D59 D62 +error(0.002673815958446297981) D31 D33 +error(0.003340032800510209492) D31 D33 D35 +error(0.001338700097173320998) D31 D33 D35 D40 D42 D44 +error(0.001338700097173320998) D31 D33 D35 D40 D42 D62 +error(0.0006697986788568588423) D31 D33 D35 D40 D58 +error(0.001338700097173320998) D31 D33 D35 D40 D60 D62 +error(0.0006697986788568588423) D31 D33 D35 D42 D60 +error(0.0006697986788568588423) D31 D33 D35 D44 D58 D60 +error(0.001338700097173320998) D31 D33 D35 D44 D62 +error(0.001338700097173320998) D31 D33 D35 D58 D60 D62 +error(0.001338700097173320998) D31 D33 D40 D42 +error(0.0006697986788568588423) D31 D33 D40 D42 D51 +error(0.0006697986788568588423) D31 D33 D40 D42 D51 D62 +error(0.0006697986788568588423) D31 D33 D40 D51 D60 +error(0.0006697986788568588423) D31 D33 D40 D51 D60 D62 +error(0.0006697986788568588423) D31 D33 D40 D58 +error(0.001338700097173320998) D31 D33 D40 D60 +error(0.001338700097173320998) D31 D33 D42 D51 D60 +error(0.0006697986788568588423) D31 D33 D42 D53 D58 +error(0.0006697986788568588423) D31 D33 D42 D53 D60 D62 +error(0.0006697986788568588423) D31 D33 D42 D58 +error(0.001338700097173320998) D31 D33 D42 D60 +error(0.0006697986788568588423) D31 D33 D44 D53 D58 D60 +error(0.0006697986788568588423) D31 D33 D44 D53 D62 +error(0.001338700097173320998) D31 D33 D51 +error(0.001338700097173320998) D31 D33 D53 +error(0.001338700097173320998) D31 D33 D53 D58 D60 D62 +error(0.001338700097173320998) D31 D33 D58 D60 +error(0.0006697986788568588423) D31 D35 D37 D40 D49 +error(0.0006697986788568588423) D31 D35 D37 D49 D58 +error(0.0006697986788568588423) D31 D35 D40 D41 D44 D53 +error(0.0006697986788568588423) D31 D35 D40 D41 D53 D62 +error(0.0006697986788568588423) D31 D35 D40 D42 D44 D53 +error(0.0006697986788568588423) D31 D35 D40 D42 D53 D62 +error(0.001338700097173320998) D31 D35 D40 D49 D58 +error(0.0006697986788568588423) D31 D35 D40 D49 D60 +error(0.004005357180252827609) D31 D35 D44 D53 D62 +error(0.001338700097173320998) D31 D35 D49 +error(0.0006697986788568588423) D31 D35 D49 D58 D60 +error(0.004005357180252827609) D31 D35 D53 +error(0.0006697986788568588423) D31 D36 D37 D46 +error(0.0006697986788568588423) D31 D36 D46 D55 +error(0.004005357180252827609) D31 D37 D46 D55 +error(0.0006697986788568588423) D31 D37 D46 D58 +error(0.001338700097173320998) D31 D40 D49 D55 +error(0.001338700097173320998) D31 D40 D49 D55 D56 +error(0.001338700097173320998) D31 D40 D49 D55 D58 D59 +error(0.001338700097173320998) D31 D40 D49 D55 D58 D60 +error(0.004005357180252827609) D31 D40 D49 D55 D62 +error(0.002673815958446297981) D31 D40 D49 D58 +error(0.0006697986788568588423) D31 D40 D49 D59 D62 +error(0.0006697986788568588423) D31 D40 D49 D60 D62 +error(0.0006697986788568588423) D31 D40 D50 D53 D55 D58 D59 +error(0.0006697986788568588423) D31 D40 D50 D53 D55 D62 +error(0.0006697986788568588423) D31 D40 D51 D53 D55 D58 D60 +error(0.0006697986788568588423) D31 D40 D51 D53 D55 D62 +error(0.0006697986788568588423) D31 D40 D51 D55 +error(0.0006697986788568588423) D31 D40 D51 D55 D58 D60 +error(0.0006697986788568588423) D31 D41 D50 D53 D56 D58 +error(0.0006697986788568588423) D31 D41 D50 D53 D56 D59 D62 +error(0.0006697986788568588423) D31 D42 D51 D53 D58 +error(0.0006697986788568588423) D31 D42 D51 D53 D60 D62 +error(0.0006697986788568588423) D31 D42 D51 D58 +error(0.0006697986788568588423) D31 D42 D51 D60 +error(0.004005357180252827609) D31 D46 +error(0.0006697986788568588423) D31 D46 D55 D58 +error(0.007978628588222850399) D31 D49 +error(0.0006697986788568588423) D31 D49 D55 D56 D58 +error(0.0006697986788568588423) D31 D49 D55 D58 +error(0.0006697986788568588423) D31 D49 D56 D58 D59 +error(0.001338700097173320998) D31 D49 D58 D59 D62 +error(0.0006697986788568588423) D31 D49 D58 D60 +error(0.001338700097173320998) D31 D49 D58 D60 D62 +error(0.001338700097173320998) D31 D50 D53 +error(0.001338700097173320998) D31 D50 D53 D58 D59 D62 +error(0.001338700097173320998) D31 D51 +error(0.001338700097173320998) D31 D51 D53 +error(0.001338700097173320998) D31 D51 D53 D58 D60 D62 +error(0.001338700097173320998) D31 D51 D58 D60 +error(0.002673815958446297981) D32 D34 +error(0.0006697986788568588423) D32 D34 D38 D39 D48 D59 +error(0.0006697986788568588423) D32 D34 D38 D48 D57 D59 +error(0.001338700097173320998) D32 D34 D39 D48 D57 +error(0.0006697986788568588423) D32 D34 D39 D48 D59 D61 +error(0.001338700097173320998) D32 D34 D41 D43 L0 +error(0.0006697986788568588423) D32 D34 D41 D59 +error(0.001338700097173320998) D32 D34 D41 D61 L0 +error(0.0006697986788568588423) D32 D34 D43 D57 D59 +error(0.0006697986788568588423) D32 D34 D43 D57 D61 L0 +error(0.0006697986788568588423) D32 D34 D43 D61 +error(0.001338700097173320998) D32 D34 D48 +error(0.0006697986788568588423) D32 D34 D48 D57 D59 D61 +error(0.001338700097173320998) D32 D34 D59 D61 L0 +error(0.002673815958446297981) D32 D35 +error(0.0006697986788568588423) D32 D35 D38 D40 D49 D59 +error(0.0006697986788568588423) D32 D35 D38 D49 D58 D59 +error(0.001338700097173320998) D32 D35 D40 D49 D58 +error(0.0006697986788568588423) D32 D35 D40 D49 D59 D62 +error(0.001338700097173320998) D32 D35 D41 D44 L0 +error(0.0006697986788568588423) D32 D35 D41 D59 +error(0.001338700097173320998) D32 D35 D41 D62 L0 +error(0.0006697986788568588423) D32 D35 D44 D58 D59 +error(0.0006697986788568588423) D32 D35 D44 D58 D62 L0 +error(0.0006697986788568588423) D32 D35 D44 D62 +error(0.001338700097173320998) D32 D35 D49 +error(0.0006697986788568588423) D32 D35 D49 D58 D59 D62 +error(0.001338700097173320998) D32 D35 D59 D62 L0 +error(0.0006697986788568588423) D32 D39 D41 D43 D52 +error(0.0006697986788568588423) D32 D39 D41 D52 D61 +error(0.0006697986788568588423) D32 D40 D41 D44 D53 +error(0.0006697986788568588423) D32 D40 D41 D53 D62 +error(0.0006697986788568588423) D32 D41 D43 D52 L0 +error(0.0006697986788568588423) D32 D41 D44 D53 L0 +error(0.001338700097173320998) D32 D41 D50 D56 D57 +error(0.001338700097173320998) D32 D41 D50 D56 D58 +error(0.001338700097173320998) D32 D41 D50 D56 D59 D61 +error(0.001338700097173320998) D32 D41 D50 D56 D59 D62 +error(0.004005357180252827609) D32 D41 D50 D56 L0 +error(0.002673815958446297981) D32 D41 D50 D59 +error(0.0006697986788568588423) D32 D41 D50 D61 L0 +error(0.0006697986788568588423) D32 D41 D50 D62 L0 +error(0.0006697986788568588423) D32 D41 D52 D56 D59 D61 +error(0.0006697986788568588423) D32 D41 D52 D56 L0 +error(0.0006697986788568588423) D32 D41 D52 D61 L0 +error(0.0006697986788568588423) D32 D41 D53 D56 D59 D62 +error(0.0006697986788568588423) D32 D41 D53 D56 L0 +error(0.0006697986788568588423) D32 D41 D53 D62 L0 +error(0.0006697986788568588423) D32 D43 D52 D57 D59 +error(0.0006697986788568588423) D32 D43 D52 D57 D61 L0 +error(0.001338700097173320998) D32 D43 D52 D61 +error(0.0006697986788568588423) D32 D44 D53 D58 D59 +error(0.0006697986788568588423) D32 D44 D53 D58 D62 L0 +error(0.001338700097173320998) D32 D44 D53 D62 +error(0.007978628588222850399) D32 D50 +error(0.0006697986788568588423) D32 D50 D56 D57 D59 +error(0.0006697986788568588423) D32 D50 D56 D58 D59 +error(0.0006697986788568588423) D32 D50 D57 D59 D61 +error(0.0006697986788568588423) D32 D50 D58 D59 D62 +error(0.001338700097173320998) D32 D50 D59 D61 L0 +error(0.001338700097173320998) D32 D50 D59 D62 L0 +error(0.002673815958446297981) D32 D52 +error(0.001338700097173320998) D32 D52 D59 D61 L0 +error(0.002673815958446297981) D32 D53 +error(0.001338700097173320998) D32 D53 D59 D62 L0 +error(0.005995987492949031786) D33 +error(0.002673815958446297981) D33 D35 +error(0.001338700097173320998) D33 D35 D40 D49 D58 +error(0.0006697986788568588423) D33 D35 D40 D49 D60 +error(0.0006697986788568588423) D33 D35 D40 D49 D60 D62 +error(0.001338700097173320998) D33 D35 D42 D44 L0 +error(0.0006697986788568588423) D33 D35 D42 D60 +error(0.001338700097173320998) D33 D35 D42 D62 L0 +error(0.0006697986788568588423) D33 D35 D44 D58 D60 +error(0.0006697986788568588423) D33 D35 D44 D58 D62 L0 +error(0.0006697986788568588423) D33 D35 D44 D62 +error(0.001338700097173320998) D33 D35 D49 +error(0.0006697986788568588423) D33 D35 D49 D58 D60 +error(0.0006697986788568588423) D33 D35 D49 D58 D60 D62 +error(0.001338700097173320998) D33 D35 D60 D62 L0 +error(0.0006697986788568588423) D33 D40 D42 D44 D53 +error(0.0006697986788568588423) D33 D40 D42 D53 D62 +error(0.0006697986788568588423) D33 D42 D44 D53 L0 +error(0.001338700097173320998) D33 D42 D51 D58 +error(0.002673815958446297981) D33 D42 D51 D60 +error(0.001338700097173320998) D33 D42 D51 D60 D62 +error(0.0006697986788568588423) D33 D42 D51 D62 L0 +error(0.004669790293214320931) D33 D42 D51 L0 +error(0.0006697986788568588423) D33 D42 D53 D60 D62 +error(0.0006697986788568588423) D33 D42 D53 D62 L0 +error(0.0006697986788568588423) D33 D42 D53 L0 +error(0.001338700097173320998) D33 D42 D60 +error(0.002673815958446297981) D33 D42 L0 +error(0.0006697986788568588423) D33 D44 D53 D58 D60 +error(0.0006697986788568588423) D33 D44 D53 D58 D62 L0 +error(0.001338700097173320998) D33 D44 D53 D62 +error(0.006657753962803452177) D33 D51 +error(0.0006697986788568588423) D33 D51 D58 D60 +error(0.0006697986788568588423) D33 D51 D58 D60 D62 +error(0.001338700097173320998) D33 D51 D60 D62 L0 +error(0.001338700097173320998) D33 D51 D60 L0 +error(0.002673815958446297981) D33 D53 +error(0.001338700097173320998) D33 D53 D60 D62 L0 +error(0.001338700097173320998) D33 D60 L0 +error(0.003340032800510209492) D34 +error(0.0006697986788568588423) D34 D38 D39 D48 +error(0.0006697986788568588423) D34 D38 D48 D57 +error(0.0006697986788568588423) D34 D39 D41 D50 D61 +error(0.004005357180252827609) D34 D39 D48 D57 +error(0.0006697986788568588423) D34 D39 D48 D61 +error(0.0006697986788568588423) D34 D39 D50 D59 D61 +error(0.0006697986788568588423) D34 D41 D43 D52 L0 +error(0.001338700097173320998) D34 D41 D50 D59 +error(0.0006697986788568588423) D34 D41 D50 D61 L0 +error(0.0006697986788568588423) D34 D41 D52 D61 L0 +error(0.001338700097173320998) D34 D43 D52 D57 +error(0.001338700097173320998) D34 D43 D52 D57 D59 +error(0.004005357180252827609) D34 D43 D52 D57 D61 L0 +error(0.002673815958446297981) D34 D43 D52 D61 +error(0.0006697986788568588423) D34 D43 D52 L0 +error(0.0006697986788568588423) D34 D43 D57 +error(0.0006697986788568588423) D34 D43 D57 D61 L0 +error(0.0006697986788568588423) D34 D43 D61 +error(0.002006705456917235505) D34 D43 L0 +error(0.004005357180252827609) D34 D48 +error(0.0006697986788568588423) D34 D48 D57 D61 +error(0.001338700097173320998) D34 D50 +error(0.0006697986788568588423) D34 D50 D59 D61 L0 +error(0.006657753962803452177) D34 D52 +error(0.0006697986788568588423) D34 D52 D57 D59 D61 +error(0.0006697986788568588423) D34 D52 D57 D61 +error(0.0006697986788568588423) D34 D52 D59 D61 L0 +error(0.001338700097173320998) D34 D52 D61 L0 +error(0.001338700097173320998) D34 D61 L0 +error(0.0006697986788568588423) D35 D40 D41 D50 D62 +error(0.0006697986788568588423) D35 D40 D42 D51 D62 +error(0.0006697986788568588423) D35 D40 D50 D59 D62 +error(0.0006697986788568588423) D35 D40 D51 D60 D62 +error(0.0006697986788568588423) D35 D41 D44 D53 L0 +error(0.001338700097173320998) D35 D41 D50 D59 +error(0.0006697986788568588423) D35 D41 D50 D62 L0 +error(0.0006697986788568588423) D35 D41 D53 D62 L0 +error(0.0006697986788568588423) D35 D42 D44 D53 L0 +error(0.001338700097173320998) D35 D42 D51 D60 +error(0.0006697986788568588423) D35 D42 D51 D62 L0 +error(0.0006697986788568588423) D35 D42 D53 D62 L0 +error(0.001338700097173320998) D35 D44 D53 D58 D59 +error(0.001338700097173320998) D35 D44 D53 D58 D60 +error(0.004005357180252827609) D35 D44 D53 D58 D62 L0 +error(0.002673815958446297981) D35 D44 D53 D62 +error(0.001338700097173320998) D35 D50 +error(0.0006697986788568588423) D35 D50 D59 D62 L0 +error(0.001338700097173320998) D35 D51 +error(0.0006697986788568588423) D35 D51 D60 D62 L0 +error(0.006657753962803452177) D35 D53 +error(0.0006697986788568588423) D35 D53 D58 D59 D62 +error(0.0006697986788568588423) D35 D53 D58 D60 D62 +error(0.0006697986788568588423) D35 D53 D59 D62 L0 +error(0.0006697986788568588423) D35 D53 D60 D62 L0 +error(0.003340032800510209492) D36 +error(0.002673815958446297981) D36 D37 +error(0.003340032800510209492) D36 D37 D38 +error(0.001338700097173320998) D36 D37 D56 +error(0.002673815958446297981) D36 D38 +error(0.0006697986788568588423) D36 D45 +error(0.0006697986788568588423) D36 D45 D46 +error(0.0006697986788568588423) D36 D45 D46 D47 D54 D55 +error(0.0006697986788568588423) D36 D45 D46 D47 D56 +error(0.0006697986788568588423) D36 D45 D46 D54 D55 +error(0.0006697986788568588423) D36 D45 D47 D54 +error(0.0006697986788568588423) D36 D45 D47 D56 +error(0.0006697986788568588423) D36 D45 D54 +error(0.006657753962803452177) D36 D54 +error(0.001338700097173320998) D36 D54 D55 +error(0.001338700097173320998) D36 D55 +error(0.001338700097173320998) D36 D55 D56 +error(0.005333333333333313206) D36 D56 +error(0.003340032800510209492) D37 D38 D40 +error(0.001338700097173320998) D37 D38 D58 +error(0.002673815958446297981) D37 D40 +error(0.0006697986788568588423) D37 D46 D47 D49 D55 D56 +error(0.0006697986788568588423) D37 D46 D47 D49 D58 +error(0.0006697986788568588423) D37 D46 D49 D55 +error(0.0006697986788568588423) D37 D46 D49 D58 +error(0.001338700097173320998) D37 D54 +error(0.006657753962803452177) D37 D55 +error(0.001338700097173320998) D37 D55 D56 +error(0.001338700097173320998) D37 D56 D58 +error(0.005333333333333313206) D37 D58 +error(0.002673815958446297981) D38 D39 +error(0.003340032800510209492) D38 D39 D41 +error(0.001338700097173320998) D38 D39 D59 +error(0.003340032800510209492) D38 D40 D41 +error(0.001338700097173320998) D38 D40 D59 +error(0.0006697986788568588423) D38 D47 D48 D50 D54 D56 D57 +error(0.0006697986788568588423) D38 D47 D48 D50 D54 D59 +error(0.0006697986788568588423) D38 D47 D48 D54 +error(0.0006697986788568588423) D38 D47 D48 D54 D56 D57 +error(0.0006697986788568588423) D38 D47 D49 D50 D54 D56 D58 +error(0.0006697986788568588423) D38 D47 D49 D50 D54 D59 +error(0.001338700097173320998) D38 D54 +error(0.001338700097173320998) D38 D54 D55 +error(0.001338700097173320998) D38 D54 D56 D57 +error(0.001338700097173320998) D38 D54 D56 D58 +error(0.004005357180252827609) D38 D54 D59 +error(0.007978628588222850399) D38 D56 +error(0.001338700097173320998) D38 D57 +error(0.001338700097173320998) D38 D57 D59 +error(0.001338700097173320998) D38 D58 D59 +error(0.003340032800510209492) D39 D41 D43 +error(0.001338700097173320998) D39 D41 D61 +error(0.002673815958446297981) D39 D43 +error(0.0006697986788568588423) D39 D43 D52 +error(0.0006697986788568588423) D39 D48 D50 D52 D57 D59 +error(0.0006697986788568588423) D39 D48 D50 D52 D61 +error(0.0006697986788568588423) D39 D48 D52 D57 +error(0.0006697986788568588423) D39 D48 D52 D61 +error(0.0006697986788568588423) D39 D52 D61 +error(0.001338700097173320998) D39 D56 +error(0.006657753962803452177) D39 D57 +error(0.001338700097173320998) D39 D57 D59 +error(0.001338700097173320998) D39 D59 D61 +error(0.005333333333333313206) D39 D61 +error(0.003340032800510209492) D40 D41 D44 +error(0.001338700097173320998) D40 D41 D62 +error(0.002673815958446297981) D40 D42 +error(0.003340032800510209492) D40 D42 D44 +error(0.0006697986788568588423) D40 D42 D51 +error(0.001338700097173320998) D40 D42 D62 +error(0.0006697986788568588423) D40 D49 D50 D53 D55 D58 D59 +error(0.0006697986788568588423) D40 D49 D50 D53 D55 D62 +error(0.0006697986788568588423) D40 D49 D51 D53 D55 D58 D60 +error(0.0006697986788568588423) D40 D49 D51 D53 D55 D62 +error(0.0006697986788568588423) D40 D49 D51 D55 +error(0.0006697986788568588423) D40 D49 D51 D55 D58 D60 +error(0.0006697986788568588423) D40 D51 D60 +error(0.001338700097173320998) D40 D55 +error(0.001338700097173320998) D40 D55 D56 +error(0.001338700097173320998) D40 D55 D58 D59 +error(0.001338700097173320998) D40 D55 D58 D60 +error(0.004005357180252827609) D40 D55 D62 +error(0.007978628588222850399) D40 D58 +error(0.001338700097173320998) D40 D59 D62 +error(0.001338700097173320998) D40 D60 +error(0.001338700097173320998) D40 D60 D62 +error(0.002673815958446297981) D41 D43 L0 +error(0.002673815958446297981) D41 D44 L0 +error(0.0006697986788568588423) D41 D50 D52 D56 D59 D61 +error(0.0006697986788568588423) D41 D50 D52 D56 L0 +error(0.0006697986788568588423) D41 D50 D53 D56 D59 D62 +error(0.0006697986788568588423) D41 D50 D53 D56 L0 +error(0.001338700097173320998) D41 D56 D57 +error(0.001338700097173320998) D41 D56 D58 +error(0.001338700097173320998) D41 D56 D59 D61 +error(0.001338700097173320998) D41 D56 D59 D62 +error(0.004005357180252827609) D41 D56 L0 +error(0.007978628588222850399) D41 D59 +error(0.001338700097173320998) D41 D61 L0 +error(0.001338700097173320998) D41 D62 L0 +error(0.002673815958446297981) D42 D44 L0 +error(0.0006697986788568588423) D42 D51 D53 D60 D62 +error(0.0006697986788568588423) D42 D51 D53 L0 +error(0.004669790293214320931) D42 D51 D60 +error(0.001338700097173320998) D42 D51 L0 +error(0.001338700097173320998) D42 D58 +error(0.006657753962803452177) D42 D60 +error(0.001338700097173320998) D42 D60 D62 +error(0.001338700097173320998) D42 D62 L0 +error(0.005995987492949031786) D42 L0 +error(0.0006697986788568588423) D43 D52 D57 +error(0.0006697986788568588423) D43 D52 D57 D61 L0 +error(0.001338700097173320998) D43 D52 D61 +error(0.0006697986788568588423) D43 D52 L0 +error(0.001338700097173320998) D43 D57 +error(0.001338700097173320998) D43 D57 D59 +error(0.004005357180252827609) D43 D57 D61 L0 +error(0.006657753962803452177) D43 D61 +error(0.002006705456917235505) D43 L0 +error(0.001338700097173320998) D44 D58 D59 +error(0.001338700097173320998) D44 D58 D60 +error(0.004005357180252827609) D44 D58 D62 L0 +error(0.006657753962803452177) D44 D62 +error(0.002006705456917235505) D45 +error(0.002673815958446297981) D45 D46 +error(0.003340032800510209492) D45 D46 D47 +error(0.001338700097173320998) D45 D46 D47 D54 D55 D56 +error(0.001338700097173320998) D45 D46 D47 D54 D55 D74 +error(0.0006697986788568588423) D45 D46 D47 D54 D72 +error(0.001338700097173320998) D45 D46 D47 D54 D73 D74 +error(0.0006697986788568588423) D45 D46 D47 D55 D73 +error(0.0006697986788568588423) D45 D46 D47 D56 D72 D73 +error(0.001338700097173320998) D45 D46 D47 D56 D74 +error(0.001338700097173320998) D45 D46 D47 D72 D73 D74 +error(0.0006697986788568588423) D45 D46 D49 D54 D55 D64 +error(0.0006697986788568588423) D45 D46 D49 D54 D55 D64 D74 +error(0.0006697986788568588423) D45 D46 D49 D54 D64 D73 +error(0.0006697986788568588423) D45 D46 D49 D54 D64 D73 D74 +error(0.001338700097173320998) D45 D46 D49 D55 D64 D73 +error(0.001338700097173320998) D45 D46 D49 D64 +error(0.001338700097173320998) D45 D46 D54 D55 +error(0.0006697986788568588423) D45 D46 D54 D72 +error(0.001338700097173320998) D45 D46 D54 D73 +error(0.0006697986788568588423) D45 D46 D55 D65 D72 +error(0.0006697986788568588423) D45 D46 D55 D65 D73 D74 +error(0.0006697986788568588423) D45 D46 D55 D72 +error(0.001338700097173320998) D45 D46 D55 D73 +error(0.0006697986788568588423) D45 D46 D56 D65 D72 D73 +error(0.0006697986788568588423) D45 D46 D56 D65 D74 +error(0.001338700097173320998) D45 D46 D65 +error(0.001338700097173320998) D45 D46 D65 D72 D73 D74 +error(0.001338700097173320998) D45 D46 D72 D73 +error(0.002673815958446297981) D45 D47 +error(0.001338700097173320998) D45 D47 D54 D56 +error(0.0006697986788568588423) D45 D47 D54 D63 +error(0.001338700097173320998) D45 D47 D54 D63 D72 +error(0.0006697986788568588423) D45 D47 D54 D63 D73 +error(0.0006697986788568588423) D45 D47 D54 D72 +error(0.001338700097173320998) D45 D47 D54 D74 +error(0.0006697986788568588423) D45 D47 D56 D72 +error(0.001338700097173320998) D45 D47 D56 D74 +error(0.001338700097173320998) D45 D47 D63 +error(0.0006697986788568588423) D45 D47 D63 D72 +error(0.0006697986788568588423) D45 D47 D63 D72 D73 +error(0.001338700097173320998) D45 D47 D72 D74 +error(0.0006697986788568588423) D45 D50 D54 D55 D56 D65 +error(0.0006697986788568588423) D45 D50 D54 D55 D65 D74 +error(0.0006697986788568588423) D45 D50 D54 D56 D65 +error(0.0006697986788568588423) D45 D50 D54 D65 D74 +error(0.004005357180252827609) D45 D50 D56 D65 D74 +error(0.004005357180252827609) D45 D50 D65 +error(0.002006705456917235505) D45 D54 +error(0.001338700097173320998) D45 D54 D63 +error(0.002673815958446297981) D45 D54 D63 D72 +error(0.001338700097173320998) D45 D54 D63 D72 D73 +error(0.0006697986788568588423) D45 D54 D63 D73 D74 +error(0.004669790293214320931) D45 D54 D63 D74 +error(0.0006697986788568588423) D45 D54 D64 +error(0.0006697986788568588423) D45 D54 D64 D65 D72 D73 +error(0.0006697986788568588423) D45 D54 D64 D65 D74 +error(0.0006697986788568588423) D45 D54 D64 D72 D73 +error(0.0006697986788568588423) D45 D54 D65 D72 +error(0.0006697986788568588423) D45 D54 D65 D74 +error(0.001338700097173320998) D45 D54 D72 +error(0.0006697986788568588423) D45 D55 D64 D65 D72 +error(0.0006697986788568588423) D45 D55 D64 D65 D73 D74 +error(0.0006697986788568588423) D45 D55 D64 D72 +error(0.0006697986788568588423) D45 D55 D64 D73 +error(0.0006697986788568588423) D45 D56 D65 D72 +error(0.0006697986788568588423) D45 D56 D65 D74 +error(0.006657753962803452177) D45 D63 +error(0.0006697986788568588423) D45 D63 D72 +error(0.0006697986788568588423) D45 D63 D72 D73 +error(0.001338700097173320998) D45 D63 D72 D73 D74 +error(0.001338700097173320998) D45 D63 D72 D74 +error(0.001338700097173320998) D45 D64 +error(0.001338700097173320998) D45 D64 D65 +error(0.001338700097173320998) D45 D64 D65 D72 D73 D74 +error(0.001338700097173320998) D45 D64 D72 D73 +error(0.001338700097173320998) D45 D65 +error(0.001338700097173320998) D45 D65 D72 D74 +error(0.001338700097173320998) D45 D72 +error(0.003340032800510209492) D46 D47 D49 +error(0.001338700097173320998) D46 D47 D49 D55 D56 D58 +error(0.001338700097173320998) D46 D47 D49 D55 D56 D76 +error(0.0006697986788568588423) D46 D47 D49 D55 D73 +error(0.001338700097173320998) D46 D47 D49 D55 D74 D76 +error(0.0006697986788568588423) D46 D47 D49 D56 D74 +error(0.0006697986788568588423) D46 D47 D49 D58 D73 D74 +error(0.001338700097173320998) D46 D47 D49 D58 D76 +error(0.001338700097173320998) D46 D47 D49 D73 D74 D76 +error(0.0006697986788568588423) D46 D47 D50 D54 D55 D56 D65 +error(0.0006697986788568588423) D46 D47 D50 D54 D55 D65 D74 +error(0.0006697986788568588423) D46 D47 D50 D55 D56 D65 D76 +error(0.0006697986788568588423) D46 D47 D50 D55 D65 D74 D76 +error(0.001338700097173320998) D46 D47 D50 D56 D65 D74 +error(0.001338700097173320998) D46 D47 D50 D65 +error(0.001338700097173320998) D46 D47 D54 D63 D72 +error(0.0006697986788568588423) D46 D47 D54 D63 D73 +error(0.0006697986788568588423) D46 D47 D54 D63 D73 D74 +error(0.0006697986788568588423) D46 D47 D56 D67 D72 D73 +error(0.0006697986788568588423) D46 D47 D56 D67 D72 D74 D76 +error(0.0006697986788568588423) D46 D47 D58 D67 D73 D74 +error(0.0006697986788568588423) D46 D47 D58 D67 D76 +error(0.001338700097173320998) D46 D47 D63 +error(0.0006697986788568588423) D46 D47 D63 D72 D73 +error(0.0006697986788568588423) D46 D47 D63 D72 D73 D74 +error(0.001338700097173320998) D46 D47 D67 +error(0.001338700097173320998) D46 D47 D67 D73 D74 D76 +error(0.002673815958446297981) D46 D49 +error(0.001338700097173320998) D46 D49 D55 D58 +error(0.0006697986788568588423) D46 D49 D55 D73 +error(0.001338700097173320998) D46 D49 D55 D76 +error(0.0006697986788568588423) D46 D49 D58 D73 +error(0.001338700097173320998) D46 D49 D58 D76 +error(0.001338700097173320998) D46 D49 D73 D76 +error(0.0006697986788568588423) D46 D53 D55 D56 D58 D67 +error(0.0006697986788568588423) D46 D53 D55 D56 D67 D76 +error(0.0006697986788568588423) D46 D53 D55 D58 D67 +error(0.0006697986788568588423) D46 D53 D55 D67 D76 +error(0.004005357180252827609) D46 D53 D58 D67 D76 +error(0.004005357180252827609) D46 D53 D67 +error(0.001338700097173320998) D46 D55 D64 D72 +error(0.002673815958446297981) D46 D55 D64 D73 +error(0.001338700097173320998) D46 D55 D64 D73 D74 +error(0.0006697986788568588423) D46 D55 D64 D74 D76 +error(0.004669790293214320931) D46 D55 D64 D76 +error(0.0006697986788568588423) D46 D55 D65 D67 D73 D74 +error(0.0006697986788568588423) D46 D55 D65 D67 D76 +error(0.0006697986788568588423) D46 D55 D67 D73 +error(0.0006697986788568588423) D46 D55 D67 D76 +error(0.0006697986788568588423) D46 D56 D65 D67 D72 D73 +error(0.0006697986788568588423) D46 D56 D65 D67 D72 D74 D76 +error(0.0006697986788568588423) D46 D58 D67 D73 +error(0.0006697986788568588423) D46 D58 D67 D76 +error(0.006657753962803452177) D46 D64 +error(0.0006697986788568588423) D46 D64 D72 D73 +error(0.0006697986788568588423) D46 D64 D72 D73 D74 +error(0.001338700097173320998) D46 D64 D73 D74 D76 +error(0.001338700097173320998) D46 D64 D73 D76 +error(0.001338700097173320998) D46 D65 D67 +error(0.001338700097173320998) D46 D65 D67 D73 D74 D76 +error(0.001338700097173320998) D46 D67 +error(0.001338700097173320998) D46 D67 D73 D76 +error(0.002673815958446297981) D47 D48 +error(0.003340032800510209492) D47 D48 D50 +error(0.001338700097173320998) D47 D48 D50 D56 D57 D59 +error(0.001338700097173320998) D47 D48 D50 D56 D57 D77 +error(0.0006697986788568588423) D47 D48 D50 D56 D74 +error(0.001338700097173320998) D47 D48 D50 D56 D75 D77 +error(0.0006697986788568588423) D47 D48 D50 D57 D75 +error(0.0006697986788568588423) D47 D48 D50 D59 D74 D75 +error(0.001338700097173320998) D47 D48 D50 D59 D77 +error(0.001338700097173320998) D47 D48 D50 D74 D75 D77 +error(0.0006697986788568588423) D47 D48 D52 D56 D57 D66 +error(0.0006697986788568588423) D47 D48 D52 D56 D57 D66 D77 +error(0.0006697986788568588423) D47 D48 D52 D56 D66 D75 +error(0.0006697986788568588423) D47 D48 D52 D56 D66 D75 D77 +error(0.001338700097173320998) D47 D48 D52 D57 D66 D75 +error(0.001338700097173320998) D47 D48 D52 D66 +error(0.001338700097173320998) D47 D48 D56 D57 +error(0.0006697986788568588423) D47 D48 D56 D74 +error(0.001338700097173320998) D47 D48 D56 D75 +error(0.0006697986788568588423) D47 D48 D57 D68 D74 +error(0.0006697986788568588423) D47 D48 D57 D68 D75 D77 +error(0.0006697986788568588423) D47 D48 D57 D74 +error(0.001338700097173320998) D47 D48 D57 D75 +error(0.0006697986788568588423) D47 D48 D59 D68 D74 D75 +error(0.0006697986788568588423) D47 D48 D59 D68 D77 +error(0.001338700097173320998) D47 D48 D68 +error(0.001338700097173320998) D47 D48 D68 D74 D75 D77 +error(0.001338700097173320998) D47 D48 D74 D75 +error(0.003340032800510209492) D47 D49 D50 +error(0.001338700097173320998) D47 D49 D50 D56 D58 D59 +error(0.001338700097173320998) D47 D49 D50 D56 D58 D77 +error(0.0006697986788568588423) D47 D49 D50 D56 D74 +error(0.001338700097173320998) D47 D49 D50 D56 D76 D77 +error(0.0006697986788568588423) D47 D49 D50 D58 D76 +error(0.0006697986788568588423) D47 D49 D50 D59 D74 D76 +error(0.001338700097173320998) D47 D49 D50 D59 D77 +error(0.001338700097173320998) D47 D49 D50 D74 D76 D77 +error(0.0006697986788568588423) D47 D49 D53 D55 D56 D58 D67 +error(0.0006697986788568588423) D47 D49 D53 D55 D56 D67 D76 +error(0.0006697986788568588423) D47 D49 D53 D56 D58 D67 D77 +error(0.0006697986788568588423) D47 D49 D53 D56 D67 D76 D77 +error(0.001338700097173320998) D47 D49 D53 D58 D67 D76 +error(0.001338700097173320998) D47 D49 D53 D67 +error(0.0006697986788568588423) D47 D49 D54 D55 D64 D74 +error(0.0006697986788568588423) D47 D49 D54 D64 D73 D74 +error(0.001338700097173320998) D47 D49 D55 D64 D73 +error(0.0006697986788568588423) D47 D49 D55 D64 D74 D76 +error(0.0006697986788568588423) D47 D49 D58 D68 D73 D74 +error(0.0006697986788568588423) D47 D49 D58 D68 D73 D76 D77 +error(0.0006697986788568588423) D47 D49 D59 D68 D74 D76 +error(0.0006697986788568588423) D47 D49 D59 D68 D77 +error(0.001338700097173320998) D47 D49 D64 +error(0.0006697986788568588423) D47 D49 D64 D73 D74 D76 +error(0.001338700097173320998) D47 D49 D68 +error(0.001338700097173320998) D47 D49 D68 D74 D76 D77 +error(0.0006697986788568588423) D47 D50 D54 D56 D65 +error(0.0006697986788568588423) D47 D50 D54 D65 D74 +error(0.001338700097173320998) D47 D50 D56 D65 D74 +error(0.0006697986788568588423) D47 D50 D56 D65 D75 +error(0.001338700097173320998) D47 D50 D65 +error(0.0006697986788568588423) D47 D50 D65 D74 D75 +error(0.0006697986788568588423) D47 D54 D63 +error(0.004005357180252827609) D47 D54 D63 D72 +error(0.0006697986788568588423) D47 D54 D63 D74 +error(0.0006697986788568588423) D47 D56 D57 D59 D68 +error(0.0006697986788568588423) D47 D56 D57 D68 D77 +error(0.0006697986788568588423) D47 D56 D58 D59 D68 +error(0.0006697986788568588423) D47 D56 D58 D68 D77 +error(0.001338700097173320998) D47 D56 D65 D72 +error(0.001338700097173320998) D47 D56 D65 D72 D73 +error(0.001338700097173320998) D47 D56 D65 D72 D74 D75 +error(0.001338700097173320998) D47 D56 D65 D72 D74 D76 +error(0.004005357180252827609) D47 D56 D65 D72 D77 +error(0.002673815958446297981) D47 D56 D65 D74 +error(0.0006697986788568588423) D47 D56 D65 D75 D77 +error(0.0006697986788568588423) D47 D56 D65 D76 D77 +error(0.0006697986788568588423) D47 D56 D66 D68 D72 D74 D75 +error(0.0006697986788568588423) D47 D56 D66 D68 D72 D77 +error(0.0006697986788568588423) D47 D56 D66 D72 +error(0.0006697986788568588423) D47 D56 D66 D72 D74 D75 +error(0.0006697986788568588423) D47 D56 D67 D68 D72 D74 D76 +error(0.0006697986788568588423) D47 D56 D67 D68 D72 D77 +error(0.0006697986788568588423) D47 D57 D66 D68 D74 +error(0.0006697986788568588423) D47 D57 D66 D68 D75 D77 +error(0.0006697986788568588423) D47 D57 D66 D74 +error(0.0006697986788568588423) D47 D57 D66 D75 +error(0.0006697986788568588423) D47 D58 D67 D68 D73 D74 +error(0.0006697986788568588423) D47 D58 D67 D68 D73 D76 D77 +error(0.004005357180252827609) D47 D59 D68 D77 +error(0.004005357180252827609) D47 D63 +error(0.0006697986788568588423) D47 D63 D72 +error(0.0006697986788568588423) D47 D63 D72 D74 +error(0.007978628588222850399) D47 D65 +error(0.0006697986788568588423) D47 D65 D72 D73 D74 +error(0.0006697986788568588423) D47 D65 D72 D74 +error(0.0006697986788568588423) D47 D65 D73 D74 D76 +error(0.0006697986788568588423) D47 D65 D74 D75 +error(0.001338700097173320998) D47 D65 D74 D75 D77 +error(0.001338700097173320998) D47 D65 D74 D76 D77 +error(0.001338700097173320998) D47 D66 +error(0.001338700097173320998) D47 D66 D68 +error(0.001338700097173320998) D47 D66 D68 D74 D75 D77 +error(0.001338700097173320998) D47 D66 D74 D75 +error(0.001338700097173320998) D47 D67 D68 +error(0.001338700097173320998) D47 D67 D68 D74 D76 D77 +error(0.004005357180252827609) D47 D68 +error(0.003340032800510209492) D48 D50 D52 +error(0.001338700097173320998) D48 D50 D52 D57 D59 D61 +error(0.001338700097173320998) D48 D50 D52 D57 D59 D79 +error(0.0006697986788568588423) D48 D50 D52 D57 D75 +error(0.001338700097173320998) D48 D50 D52 D57 D77 D79 +error(0.0006697986788568588423) D48 D50 D52 D59 D77 +error(0.0006697986788568588423) D48 D50 D52 D61 D75 D77 +error(0.001338700097173320998) D48 D50 D52 D61 D79 +error(0.001338700097173320998) D48 D50 D52 D75 D77 D79 +error(0.0006697986788568588423) D48 D50 D56 D57 D59 D68 +error(0.0006697986788568588423) D48 D50 D56 D57 D68 D77 +error(0.001338700097173320998) D48 D50 D56 D65 D74 +error(0.0006697986788568588423) D48 D50 D56 D65 D75 +error(0.0006697986788568588423) D48 D50 D56 D65 D75 D77 +error(0.0006697986788568588423) D48 D50 D57 D59 D68 D79 +error(0.0006697986788568588423) D48 D50 D57 D68 D77 D79 +error(0.001338700097173320998) D48 D50 D59 D68 D77 +error(0.0006697986788568588423) D48 D50 D59 D70 D74 D75 +error(0.0006697986788568588423) D48 D50 D59 D70 D74 D77 D79 +error(0.0006697986788568588423) D48 D50 D61 D70 D75 D77 +error(0.0006697986788568588423) D48 D50 D61 D70 D79 +error(0.001338700097173320998) D48 D50 D65 +error(0.0006697986788568588423) D48 D50 D65 D74 D75 +error(0.0006697986788568588423) D48 D50 D65 D74 D75 D77 +error(0.001338700097173320998) D48 D50 D68 +error(0.001338700097173320998) D48 D50 D70 +error(0.001338700097173320998) D48 D50 D70 D75 D77 D79 +error(0.002673815958446297981) D48 D52 +error(0.0006697986788568588423) D48 D52 D57 D59 D61 D70 +error(0.0006697986788568588423) D48 D52 D57 D59 D70 D79 +error(0.001338700097173320998) D48 D52 D57 D61 +error(0.0006697986788568588423) D48 D52 D57 D61 D70 +error(0.0006697986788568588423) D48 D52 D57 D70 D79 +error(0.0006697986788568588423) D48 D52 D57 D75 +error(0.001338700097173320998) D48 D52 D57 D79 +error(0.004005357180252827609) D48 D52 D61 D70 D79 +error(0.0006697986788568588423) D48 D52 D61 D75 +error(0.001338700097173320998) D48 D52 D61 D79 +error(0.004005357180252827609) D48 D52 D70 +error(0.001338700097173320998) D48 D52 D75 D79 +error(0.001338700097173320998) D48 D57 D66 D74 +error(0.002673815958446297981) D48 D57 D66 D75 +error(0.001338700097173320998) D48 D57 D66 D75 D77 +error(0.0006697986788568588423) D48 D57 D66 D77 D79 +error(0.004669790293214320931) D48 D57 D66 D79 +error(0.0006697986788568588423) D48 D57 D68 D70 D75 D77 +error(0.0006697986788568588423) D48 D57 D68 D70 D79 +error(0.0006697986788568588423) D48 D57 D70 D75 +error(0.0006697986788568588423) D48 D57 D70 D79 +error(0.0006697986788568588423) D48 D59 D68 D70 D74 D75 +error(0.0006697986788568588423) D48 D59 D68 D70 D74 D77 D79 +error(0.0006697986788568588423) D48 D61 D70 D75 +error(0.0006697986788568588423) D48 D61 D70 D79 +error(0.006657753962803452177) D48 D66 +error(0.0006697986788568588423) D48 D66 D74 D75 +error(0.0006697986788568588423) D48 D66 D74 D75 D77 +error(0.001338700097173320998) D48 D66 D75 D77 D79 +error(0.001338700097173320998) D48 D66 D75 D79 +error(0.001338700097173320998) D48 D68 D70 +error(0.001338700097173320998) D48 D68 D70 D75 D77 D79 +error(0.001338700097173320998) D48 D70 +error(0.001338700097173320998) D48 D70 D75 D79 +error(0.003340032800510209492) D49 D50 D53 +error(0.001338700097173320998) D49 D50 D53 D58 D59 D62 +error(0.001338700097173320998) D49 D50 D53 D58 D59 D80 +error(0.0006697986788568588423) D49 D50 D53 D58 D76 +error(0.001338700097173320998) D49 D50 D53 D58 D77 D80 +error(0.0006697986788568588423) D49 D50 D53 D59 D77 +error(0.0006697986788568588423) D49 D50 D53 D62 D76 D77 +error(0.001338700097173320998) D49 D50 D53 D62 D80 +error(0.001338700097173320998) D49 D50 D53 D76 D77 D80 +error(0.0006697986788568588423) D49 D50 D55 D56 D65 D76 +error(0.0006697986788568588423) D49 D50 D55 D65 D74 D76 +error(0.0006697986788568588423) D49 D50 D56 D58 D59 D68 +error(0.0006697986788568588423) D49 D50 D56 D58 D68 D77 +error(0.001338700097173320998) D49 D50 D56 D65 D74 +error(0.0006697986788568588423) D49 D50 D56 D65 D76 D77 +error(0.0006697986788568588423) D49 D50 D58 D59 D68 D80 +error(0.0006697986788568588423) D49 D50 D58 D68 D77 D80 +error(0.001338700097173320998) D49 D50 D59 D68 D77 +error(0.0006697986788568588423) D49 D50 D59 D71 D74 D76 +error(0.0006697986788568588423) D49 D50 D59 D71 D74 D77 D80 +error(0.0006697986788568588423) D49 D50 D62 D71 D76 D77 +error(0.0006697986788568588423) D49 D50 D62 D71 D80 +error(0.001338700097173320998) D49 D50 D65 +error(0.0006697986788568588423) D49 D50 D65 D74 D76 D77 +error(0.001338700097173320998) D49 D50 D68 +error(0.001338700097173320998) D49 D50 D71 +error(0.001338700097173320998) D49 D50 D71 D76 D77 D80 +error(0.002673815958446297981) D49 D51 +error(0.003340032800510209492) D49 D51 D53 +error(0.001338700097173320998) D49 D51 D53 D58 D60 D62 +error(0.001338700097173320998) D49 D51 D53 D58 D60 D80 +error(0.0006697986788568588423) D49 D51 D53 D58 D76 +error(0.001338700097173320998) D49 D51 D53 D58 D78 D80 +error(0.0006697986788568588423) D49 D51 D53 D60 D78 +error(0.0006697986788568588423) D49 D51 D53 D62 D76 D78 +error(0.001338700097173320998) D49 D51 D53 D62 D80 +error(0.001338700097173320998) D49 D51 D53 D76 D78 D80 +error(0.001338700097173320998) D49 D51 D58 D60 +error(0.0006697986788568588423) D49 D51 D58 D60 D69 +error(0.0006697986788568588423) D49 D51 D58 D60 D69 D80 +error(0.0006697986788568588423) D49 D51 D58 D69 D78 +error(0.0006697986788568588423) D49 D51 D58 D69 D78 D80 +error(0.0006697986788568588423) D49 D51 D58 D76 +error(0.001338700097173320998) D49 D51 D58 D78 +error(0.001338700097173320998) D49 D51 D60 D69 D78 +error(0.0006697986788568588423) D49 D51 D60 D71 D76 +error(0.0006697986788568588423) D49 D51 D60 D71 D78 D80 +error(0.0006697986788568588423) D49 D51 D60 D76 +error(0.001338700097173320998) D49 D51 D60 D78 +error(0.0006697986788568588423) D49 D51 D62 D71 D76 D78 +error(0.0006697986788568588423) D49 D51 D62 D71 D80 +error(0.001338700097173320998) D49 D51 D69 +error(0.001338700097173320998) D49 D51 D71 +error(0.001338700097173320998) D49 D51 D71 D76 D78 D80 +error(0.001338700097173320998) D49 D51 D76 D78 +error(0.0006697986788568588423) D49 D53 D55 D58 D67 +error(0.0006697986788568588423) D49 D53 D55 D67 D76 +error(0.0006697986788568588423) D49 D53 D58 D59 D62 D71 +error(0.0006697986788568588423) D49 D53 D58 D59 D71 D80 +error(0.0006697986788568588423) D49 D53 D58 D60 D62 D71 +error(0.0006697986788568588423) D49 D53 D58 D60 D71 D80 +error(0.001338700097173320998) D49 D53 D58 D67 D76 +error(0.0006697986788568588423) D49 D53 D58 D67 D78 +error(0.004005357180252827609) D49 D53 D62 D71 D80 +error(0.001338700097173320998) D49 D53 D67 +error(0.0006697986788568588423) D49 D53 D67 D76 D78 +error(0.004005357180252827609) D49 D53 D71 +error(0.0006697986788568588423) D49 D54 D55 D64 +error(0.0006697986788568588423) D49 D54 D64 D73 +error(0.004005357180252827609) D49 D55 D64 D73 +error(0.0006697986788568588423) D49 D55 D64 D76 +error(0.001338700097173320998) D49 D58 D67 D73 +error(0.001338700097173320998) D49 D58 D67 D73 D74 +error(0.001338700097173320998) D49 D58 D67 D73 D76 D77 +error(0.001338700097173320998) D49 D58 D67 D73 D76 D78 +error(0.004005357180252827609) D49 D58 D67 D73 D80 +error(0.002673815958446297981) D49 D58 D67 D76 +error(0.0006697986788568588423) D49 D58 D67 D77 D80 +error(0.0006697986788568588423) D49 D58 D67 D78 D80 +error(0.0006697986788568588423) D49 D58 D68 D71 D73 D76 D77 +error(0.0006697986788568588423) D49 D58 D68 D71 D73 D80 +error(0.0006697986788568588423) D49 D58 D69 D71 D73 D76 D78 +error(0.0006697986788568588423) D49 D58 D69 D71 D73 D80 +error(0.0006697986788568588423) D49 D58 D69 D73 +error(0.0006697986788568588423) D49 D58 D69 D73 D76 D78 +error(0.0006697986788568588423) D49 D59 D68 D71 D74 D76 +error(0.0006697986788568588423) D49 D59 D68 D71 D74 D77 D80 +error(0.0006697986788568588423) D49 D60 D69 D71 D76 +error(0.0006697986788568588423) D49 D60 D69 D71 D78 D80 +error(0.0006697986788568588423) D49 D60 D69 D76 +error(0.0006697986788568588423) D49 D60 D69 D78 +error(0.004005357180252827609) D49 D64 +error(0.0006697986788568588423) D49 D64 D73 D76 +error(0.007978628588222850399) D49 D67 +error(0.0006697986788568588423) D49 D67 D73 D74 D76 +error(0.0006697986788568588423) D49 D67 D73 D76 +error(0.0006697986788568588423) D49 D67 D74 D76 D77 +error(0.001338700097173320998) D49 D67 D76 D77 D80 +error(0.0006697986788568588423) D49 D67 D76 D78 +error(0.001338700097173320998) D49 D67 D76 D78 D80 +error(0.001338700097173320998) D49 D68 D71 +error(0.001338700097173320998) D49 D68 D71 D76 D77 D80 +error(0.001338700097173320998) D49 D69 +error(0.001338700097173320998) D49 D69 D71 +error(0.001338700097173320998) D49 D69 D71 D76 D78 D80 +error(0.001338700097173320998) D49 D69 D76 D78 +error(0.002673815958446297981) D50 D52 +error(0.0006697986788568588423) D50 D52 D56 D57 D66 D77 +error(0.0006697986788568588423) D50 D52 D56 D66 D75 D77 +error(0.001338700097173320998) D50 D52 D57 D66 D75 +error(0.0006697986788568588423) D50 D52 D57 D66 D77 D79 +error(0.001338700097173320998) D50 D52 D59 D61 L0 +error(0.0006697986788568588423) D50 D52 D59 D77 +error(0.001338700097173320998) D50 D52 D59 D79 L0 +error(0.0006697986788568588423) D50 D52 D61 D75 D77 +error(0.0006697986788568588423) D50 D52 D61 D75 D79 L0 +error(0.0006697986788568588423) D50 D52 D61 D79 +error(0.001338700097173320998) D50 D52 D66 +error(0.0006697986788568588423) D50 D52 D66 D75 D77 D79 +error(0.001338700097173320998) D50 D52 D77 D79 L0 +error(0.002673815958446297981) D50 D53 +error(0.0006697986788568588423) D50 D53 D56 D58 D67 D77 +error(0.0006697986788568588423) D50 D53 D56 D67 D76 D77 +error(0.001338700097173320998) D50 D53 D58 D67 D76 +error(0.0006697986788568588423) D50 D53 D58 D67 D77 D80 +error(0.001338700097173320998) D50 D53 D59 D62 L0 +error(0.0006697986788568588423) D50 D53 D59 D77 +error(0.001338700097173320998) D50 D53 D59 D80 L0 +error(0.0006697986788568588423) D50 D53 D62 D76 D77 +error(0.0006697986788568588423) D50 D53 D62 D76 D80 L0 +error(0.0006697986788568588423) D50 D53 D62 D80 +error(0.001338700097173320998) D50 D53 D67 +error(0.0006697986788568588423) D50 D53 D67 D76 D77 D80 +error(0.001338700097173320998) D50 D53 D77 D80 L0 +error(0.0006697986788568588423) D50 D57 D59 D61 D70 +error(0.0006697986788568588423) D50 D57 D59 D70 D79 +error(0.0006697986788568588423) D50 D58 D59 D62 D71 +error(0.0006697986788568588423) D50 D58 D59 D71 D80 +error(0.0006697986788568588423) D50 D59 D61 D70 L0 +error(0.0006697986788568588423) D50 D59 D62 D71 L0 +error(0.001338700097173320998) D50 D59 D68 D74 D75 +error(0.001338700097173320998) D50 D59 D68 D74 D76 +error(0.001338700097173320998) D50 D59 D68 D74 D77 D79 +error(0.001338700097173320998) D50 D59 D68 D74 D77 D80 +error(0.004005357180252827609) D50 D59 D68 D74 L0 +error(0.002673815958446297981) D50 D59 D68 D77 +error(0.0006697986788568588423) D50 D59 D68 D79 L0 +error(0.0006697986788568588423) D50 D59 D68 D80 L0 +error(0.0006697986788568588423) D50 D59 D70 D74 D77 D79 +error(0.0006697986788568588423) D50 D59 D70 D74 L0 +error(0.0006697986788568588423) D50 D59 D70 D79 L0 +error(0.0006697986788568588423) D50 D59 D71 D74 D77 D80 +error(0.0006697986788568588423) D50 D59 D71 D74 L0 +error(0.0006697986788568588423) D50 D59 D71 D80 L0 +error(0.0006697986788568588423) D50 D61 D70 D75 D77 +error(0.0006697986788568588423) D50 D61 D70 D75 D79 L0 +error(0.001338700097173320998) D50 D61 D70 D79 +error(0.0006697986788568588423) D50 D62 D71 D76 D77 +error(0.0006697986788568588423) D50 D62 D71 D76 D80 L0 +error(0.001338700097173320998) D50 D62 D71 D80 +error(0.007978628588222850399) D50 D68 +error(0.0006697986788568588423) D50 D68 D74 D75 D77 +error(0.0006697986788568588423) D50 D68 D74 D76 D77 +error(0.0006697986788568588423) D50 D68 D75 D77 D79 +error(0.0006697986788568588423) D50 D68 D76 D77 D80 +error(0.001338700097173320998) D50 D68 D77 D79 L0 +error(0.001338700097173320998) D50 D68 D77 D80 L0 +error(0.002673815958446297981) D50 D70 +error(0.001338700097173320998) D50 D70 D77 D79 L0 +error(0.002673815958446297981) D50 D71 +error(0.001338700097173320998) D50 D71 D77 D80 L0 +error(0.005995987492949031786) D51 +error(0.002673815958446297981) D51 D53 +error(0.001338700097173320998) D51 D53 D58 D67 D76 +error(0.0006697986788568588423) D51 D53 D58 D67 D78 +error(0.0006697986788568588423) D51 D53 D58 D67 D78 D80 +error(0.001338700097173320998) D51 D53 D60 D62 L0 +error(0.0006697986788568588423) D51 D53 D60 D78 +error(0.001338700097173320998) D51 D53 D60 D80 L0 +error(0.0006697986788568588423) D51 D53 D62 D76 D78 +error(0.0006697986788568588423) D51 D53 D62 D76 D80 L0 +error(0.0006697986788568588423) D51 D53 D62 D80 +error(0.001338700097173320998) D51 D53 D67 +error(0.0006697986788568588423) D51 D53 D67 D76 D78 +error(0.0006697986788568588423) D51 D53 D67 D76 D78 D80 +error(0.001338700097173320998) D51 D53 D78 D80 L0 +error(0.0006697986788568588423) D51 D58 D60 D62 D71 +error(0.0006697986788568588423) D51 D58 D60 D71 D80 +error(0.0006697986788568588423) D51 D60 D62 D71 L0 +error(0.001338700097173320998) D51 D60 D69 D76 +error(0.002673815958446297981) D51 D60 D69 D78 +error(0.001338700097173320998) D51 D60 D69 D78 D80 +error(0.0006697986788568588423) D51 D60 D69 D80 L0 +error(0.004669790293214320931) D51 D60 D69 L0 +error(0.0006697986788568588423) D51 D60 D71 D78 D80 +error(0.0006697986788568588423) D51 D60 D71 D80 L0 +error(0.0006697986788568588423) D51 D60 D71 L0 +error(0.001338700097173320998) D51 D60 D78 +error(0.002673815958446297981) D51 D60 L0 +error(0.0006697986788568588423) D51 D62 D71 D76 D78 +error(0.0006697986788568588423) D51 D62 D71 D76 D80 L0 +error(0.001338700097173320998) D51 D62 D71 D80 +error(0.006657753962803452177) D51 D69 +error(0.0006697986788568588423) D51 D69 D76 D78 +error(0.0006697986788568588423) D51 D69 D76 D78 D80 +error(0.001338700097173320998) D51 D69 D78 D80 L0 +error(0.001338700097173320998) D51 D69 D78 L0 +error(0.002673815958446297981) D51 D71 +error(0.001338700097173320998) D51 D71 D78 D80 L0 +error(0.001338700097173320998) D51 D78 L0 +error(0.003340032800510209492) D52 +error(0.0006697986788568588423) D52 D56 D57 D66 +error(0.0006697986788568588423) D52 D56 D66 D75 +error(0.0006697986788568588423) D52 D57 D59 D68 D79 +error(0.004005357180252827609) D52 D57 D66 D75 +error(0.0006697986788568588423) D52 D57 D66 D79 +error(0.0006697986788568588423) D52 D57 D68 D77 D79 +error(0.0006697986788568588423) D52 D59 D61 D70 L0 +error(0.001338700097173320998) D52 D59 D68 D77 +error(0.0006697986788568588423) D52 D59 D68 D79 L0 +error(0.0006697986788568588423) D52 D59 D70 D79 L0 +error(0.001338700097173320998) D52 D61 D70 D75 +error(0.001338700097173320998) D52 D61 D70 D75 D77 +error(0.004005357180252827609) D52 D61 D70 D75 D79 L0 +error(0.002673815958446297981) D52 D61 D70 D79 +error(0.0006697986788568588423) D52 D61 D70 L0 +error(0.0006697986788568588423) D52 D61 D75 +error(0.0006697986788568588423) D52 D61 D75 D79 L0 +error(0.0006697986788568588423) D52 D61 D79 +error(0.002006705456917235505) D52 D61 L0 +error(0.004005357180252827609) D52 D66 +error(0.0006697986788568588423) D52 D66 D75 D79 +error(0.001338700097173320998) D52 D68 +error(0.0006697986788568588423) D52 D68 D77 D79 L0 +error(0.006657753962803452177) D52 D70 +error(0.0006697986788568588423) D52 D70 D75 D77 D79 +error(0.0006697986788568588423) D52 D70 D75 D79 +error(0.0006697986788568588423) D52 D70 D77 D79 L0 +error(0.001338700097173320998) D52 D70 D79 L0 +error(0.001338700097173320998) D52 D79 L0 +error(0.0006697986788568588423) D53 D58 D59 D68 D80 +error(0.0006697986788568588423) D53 D58 D60 D69 D80 +error(0.0006697986788568588423) D53 D58 D68 D77 D80 +error(0.0006697986788568588423) D53 D58 D69 D78 D80 +error(0.0006697986788568588423) D53 D59 D62 D71 L0 +error(0.001338700097173320998) D53 D59 D68 D77 +error(0.0006697986788568588423) D53 D59 D68 D80 L0 +error(0.0006697986788568588423) D53 D59 D71 D80 L0 +error(0.0006697986788568588423) D53 D60 D62 D71 L0 +error(0.001338700097173320998) D53 D60 D69 D78 +error(0.0006697986788568588423) D53 D60 D69 D80 L0 +error(0.0006697986788568588423) D53 D60 D71 D80 L0 +error(0.001338700097173320998) D53 D62 D71 D76 D77 +error(0.001338700097173320998) D53 D62 D71 D76 D78 +error(0.004005357180252827609) D53 D62 D71 D76 D80 L0 +error(0.002673815958446297981) D53 D62 D71 D80 +error(0.001338700097173320998) D53 D68 +error(0.0006697986788568588423) D53 D68 D77 D80 L0 +error(0.001338700097173320998) D53 D69 +error(0.0006697986788568588423) D53 D69 D78 D80 L0 +error(0.006657753962803452177) D53 D71 +error(0.0006697986788568588423) D53 D71 D76 D77 D80 +error(0.0006697986788568588423) D53 D71 D76 D78 D80 +error(0.0006697986788568588423) D53 D71 D77 D80 L0 +error(0.0006697986788568588423) D53 D71 D78 D80 L0 +error(0.003340032800510209492) D54 +error(0.002673815958446297981) D54 D55 +error(0.003340032800510209492) D54 D55 D56 +error(0.001338700097173320998) D54 D55 D74 +error(0.002673815958446297981) D54 D56 +error(0.0006697986788568588423) D54 D63 +error(0.0006697986788568588423) D54 D63 D64 +error(0.0006697986788568588423) D54 D63 D64 D65 D72 D73 +error(0.0006697986788568588423) D54 D63 D64 D65 D74 +error(0.0006697986788568588423) D54 D63 D64 D72 D73 +error(0.0006697986788568588423) D54 D63 D65 D72 +error(0.0006697986788568588423) D54 D63 D65 D74 +error(0.0006697986788568588423) D54 D63 D72 +error(0.006657753962803452177) D54 D72 +error(0.001338700097173320998) D54 D72 D73 +error(0.001338700097173320998) D54 D73 +error(0.001338700097173320998) D54 D73 D74 +error(0.005333333333333313206) D54 D74 +error(0.003340032800510209492) D55 D56 D58 +error(0.001338700097173320998) D55 D56 D76 +error(0.002673815958446297981) D55 D58 +error(0.0006697986788568588423) D55 D64 D65 D67 D73 D74 +error(0.0006697986788568588423) D55 D64 D65 D67 D76 +error(0.0006697986788568588423) D55 D64 D67 D73 +error(0.0006697986788568588423) D55 D64 D67 D76 +error(0.001338700097173320998) D55 D72 +error(0.006657753962803452177) D55 D73 +error(0.001338700097173320998) D55 D73 D74 +error(0.001338700097173320998) D55 D74 D76 +error(0.005333333333333313206) D55 D76 +error(0.002673815958446297981) D56 D57 +error(0.003340032800510209492) D56 D57 D59 +error(0.001338700097173320998) D56 D57 D77 +error(0.003340032800510209492) D56 D58 D59 +error(0.001338700097173320998) D56 D58 D77 +error(0.0006697986788568588423) D56 D65 D66 D68 D72 D74 D75 +error(0.0006697986788568588423) D56 D65 D66 D68 D72 D77 +error(0.0006697986788568588423) D56 D65 D66 D72 +error(0.0006697986788568588423) D56 D65 D66 D72 D74 D75 +error(0.0006697986788568588423) D56 D65 D67 D68 D72 D74 D76 +error(0.0006697986788568588423) D56 D65 D67 D68 D72 D77 +error(0.001338700097173320998) D56 D72 +error(0.001338700097173320998) D56 D72 D73 +error(0.001338700097173320998) D56 D72 D74 D75 +error(0.001338700097173320998) D56 D72 D74 D76 +error(0.004005357180252827609) D56 D72 D77 +error(0.007978628588222850399) D56 D74 +error(0.001338700097173320998) D56 D75 +error(0.001338700097173320998) D56 D75 D77 +error(0.001338700097173320998) D56 D76 D77 +error(0.003340032800510209492) D57 D59 D61 +error(0.001338700097173320998) D57 D59 D79 +error(0.002673815958446297981) D57 D61 +error(0.0006697986788568588423) D57 D61 D70 +error(0.0006697986788568588423) D57 D66 D68 D70 D75 D77 +error(0.0006697986788568588423) D57 D66 D68 D70 D79 +error(0.0006697986788568588423) D57 D66 D70 D75 +error(0.0006697986788568588423) D57 D66 D70 D79 +error(0.0006697986788568588423) D57 D70 D79 +error(0.001338700097173320998) D57 D74 +error(0.006657753962803452177) D57 D75 +error(0.001338700097173320998) D57 D75 D77 +error(0.001338700097173320998) D57 D77 D79 +error(0.005333333333333313206) D57 D79 +error(0.003340032800510209492) D58 D59 D62 +error(0.001338700097173320998) D58 D59 D80 +error(0.002673815958446297981) D58 D60 +error(0.003340032800510209492) D58 D60 D62 +error(0.0006697986788568588423) D58 D60 D69 +error(0.001338700097173320998) D58 D60 D80 +error(0.0006697986788568588423) D58 D67 D68 D71 D73 D76 D77 +error(0.0006697986788568588423) D58 D67 D68 D71 D73 D80 +error(0.0006697986788568588423) D58 D67 D69 D71 D73 D76 D78 +error(0.0006697986788568588423) D58 D67 D69 D71 D73 D80 +error(0.0006697986788568588423) D58 D67 D69 D73 +error(0.0006697986788568588423) D58 D67 D69 D73 D76 D78 +error(0.0006697986788568588423) D58 D69 D78 +error(0.001338700097173320998) D58 D73 +error(0.001338700097173320998) D58 D73 D74 +error(0.001338700097173320998) D58 D73 D76 D77 +error(0.001338700097173320998) D58 D73 D76 D78 +error(0.004005357180252827609) D58 D73 D80 +error(0.007978628588222850399) D58 D76 +error(0.001338700097173320998) D58 D77 D80 +error(0.001338700097173320998) D58 D78 +error(0.001338700097173320998) D58 D78 D80 +error(0.002673815958446297981) D59 D61 L0 +error(0.002673815958446297981) D59 D62 L0 +error(0.0006697986788568588423) D59 D68 D70 D74 D77 D79 +error(0.0006697986788568588423) D59 D68 D70 D74 L0 +error(0.0006697986788568588423) D59 D68 D71 D74 D77 D80 +error(0.0006697986788568588423) D59 D68 D71 D74 L0 +error(0.001338700097173320998) D59 D74 D75 +error(0.001338700097173320998) D59 D74 D76 +error(0.001338700097173320998) D59 D74 D77 D79 +error(0.001338700097173320998) D59 D74 D77 D80 +error(0.004005357180252827609) D59 D74 L0 +error(0.007978628588222850399) D59 D77 +error(0.001338700097173320998) D59 D79 L0 +error(0.001338700097173320998) D59 D80 L0 +error(0.002673815958446297981) D60 D62 L0 +error(0.0006697986788568588423) D60 D69 D71 D78 D80 +error(0.0006697986788568588423) D60 D69 D71 L0 +error(0.004669790293214320931) D60 D69 D78 +error(0.001338700097173320998) D60 D69 L0 +error(0.001338700097173320998) D60 D76 +error(0.006657753962803452177) D60 D78 +error(0.001338700097173320998) D60 D78 D80 +error(0.001338700097173320998) D60 D80 L0 +error(0.005995987492949031786) D60 L0 +error(0.0006697986788568588423) D61 D70 D75 +error(0.0006697986788568588423) D61 D70 D75 D79 L0 +error(0.001338700097173320998) D61 D70 D79 +error(0.0006697986788568588423) D61 D70 L0 +error(0.001338700097173320998) D61 D75 +error(0.001338700097173320998) D61 D75 D77 +error(0.004005357180252827609) D61 D75 D79 L0 +error(0.006657753962803452177) D61 D79 +error(0.002006705456917235505) D61 L0 +error(0.001338700097173320998) D62 D76 D77 +error(0.001338700097173320998) D62 D76 D78 +error(0.004005357180252827609) D62 D76 D80 L0 +error(0.006657753962803452177) D62 D80 +error(0.01257390183676828158) D63 +error(0.004005357180252827609) D63 D64 +error(0.003340032800510209492) D63 D64 D65 +error(0.001338700097173320998) D63 D64 D65 D72 D73 D74 +error(0.001338700097173320998) D63 D64 D65 D72 D73 D83 +error(0.0006697986788568588423) D63 D64 D65 D72 D81 +error(0.001338700097173320998) D63 D64 D65 D72 D82 D83 +error(0.0006697986788568588423) D63 D64 D65 D73 D82 +error(0.0006697986788568588423) D63 D64 D65 D74 D81 D82 +error(0.001338700097173320998) D63 D64 D65 D74 D83 +error(0.001338700097173320998) D63 D64 D65 D81 D82 D83 +error(0.001338700097173320998) D63 D64 D67 +error(0.0006697986788568588423) D63 D64 D67 D72 D73 +error(0.0006697986788568588423) D63 D64 D67 D72 D73 D83 +error(0.0006697986788568588423) D63 D64 D67 D72 D82 +error(0.0006697986788568588423) D63 D64 D67 D72 D82 D83 +error(0.001338700097173320998) D63 D64 D67 D73 D82 +error(0.001338700097173320998) D63 D64 D72 D73 +error(0.0006697986788568588423) D63 D64 D72 D81 +error(0.001338700097173320998) D63 D64 D72 D82 +error(0.001338700097173320998) D63 D64 D73 D81 +error(0.001338700097173320998) D63 D64 D73 D82 +error(0.0006697986788568588423) D63 D64 D73 D82 D83 +error(0.0006697986788568588423) D63 D64 D74 D81 D82 +error(0.0006697986788568588423) D63 D64 D74 D83 +error(0.001338700097173320998) D63 D64 D81 D82 +error(0.001338700097173320998) D63 D64 D81 D82 D83 +error(0.004005357180252827609) D63 D65 +error(0.0006697986788568588423) D63 D65 D72 +error(0.001338700097173320998) D63 D65 D72 D74 +error(0.002006705456917235505) D63 D65 D72 D81 +error(0.0006697986788568588423) D63 D65 D72 D82 +error(0.001338700097173320998) D63 D65 D72 D83 +error(0.0006697986788568588423) D63 D65 D74 D81 +error(0.001338700097173320998) D63 D65 D74 D83 +error(0.0006697986788568588423) D63 D65 D81 +error(0.0006697986788568588423) D63 D65 D81 D82 +error(0.001338700097173320998) D63 D65 D81 D83 +error(0.004005357180252827609) D63 D68 +error(0.0006697986788568588423) D63 D68 D72 D73 D74 +error(0.0006697986788568588423) D63 D68 D72 D73 D83 +error(0.0006697986788568588423) D63 D68 D72 D74 +error(0.0006697986788568588423) D63 D68 D72 D83 +error(0.004005357180252827609) D63 D68 D74 D83 +error(0.004005357180252827609) D63 D72 +error(0.004669790293214320931) D63 D72 D81 +error(0.002673815958446297981) D63 D72 D81 D82 +error(0.0006697986788568588423) D63 D72 D82 D83 +error(0.005995987492949031786) D63 D72 D83 +error(0.001338700097173320998) D63 D73 D81 +error(0.0006697986788568588423) D63 D73 D82 +error(0.0006697986788568588423) D63 D73 D82 D83 +error(0.0006697986788568588423) D63 D74 D81 +error(0.0006697986788568588423) D63 D74 D83 +error(0.002006705456917235505) D63 D81 +error(0.002006705456917235505) D63 D81 D82 +error(0.002673815958446297981) D63 D81 D82 D83 +error(0.002673815958446297981) D63 D81 D83 +error(0.009295966703663446212) D64 +error(0.002673815958446297981) D64 D65 +error(0.003340032800510209492) D64 D65 D67 +error(0.001338700097173320998) D64 D65 D67 D73 D74 D76 +error(0.001338700097173320998) D64 D65 D67 D73 D74 D85 +error(0.0006697986788568588423) D64 D65 D67 D73 D82 +error(0.001338700097173320998) D64 D65 D67 D73 D83 D85 +error(0.0006697986788568588423) D64 D65 D67 D74 D83 +error(0.0006697986788568588423) D64 D65 D67 D76 D82 D83 +error(0.001338700097173320998) D64 D65 D67 D76 D85 +error(0.001338700097173320998) D64 D65 D67 D82 D83 D85 +error(0.001338700097173320998) D64 D65 D68 +error(0.0006697986788568588423) D64 D65 D68 D72 D73 D74 +error(0.0006697986788568588423) D64 D65 D68 D72 D73 D83 +error(0.0006697986788568588423) D64 D65 D68 D73 D74 D85 +error(0.0006697986788568588423) D64 D65 D68 D73 D83 D85 +error(0.001338700097173320998) D64 D65 D68 D74 D83 +error(0.001338700097173320998) D64 D65 D72 D81 +error(0.0006697986788568588423) D64 D65 D72 D82 +error(0.0006697986788568588423) D64 D65 D72 D82 D83 +error(0.0006697986788568588423) D64 D65 D74 D81 D82 +error(0.0006697986788568588423) D64 D65 D74 D81 D83 D85 +error(0.0006697986788568588423) D64 D65 D76 D82 D83 +error(0.0006697986788568588423) D64 D65 D76 D85 +error(0.0006697986788568588423) D64 D65 D81 D82 +error(0.0006697986788568588423) D64 D65 D81 D82 D83 +error(0.001338700097173320998) D64 D65 D82 D83 D85 +error(0.002673815958446297981) D64 D67 +error(0.001338700097173320998) D64 D67 D73 D76 +error(0.0006697986788568588423) D64 D67 D73 D82 +error(0.001338700097173320998) D64 D67 D73 D85 +error(0.0006697986788568588423) D64 D67 D76 D82 +error(0.001338700097173320998) D64 D67 D76 D85 +error(0.001338700097173320998) D64 D67 D82 D85 +error(0.004005357180252827609) D64 D71 +error(0.0006697986788568588423) D64 D71 D73 D74 D76 +error(0.0006697986788568588423) D64 D71 D73 D74 D85 +error(0.0006697986788568588423) D64 D71 D73 D76 +error(0.0006697986788568588423) D64 D71 D73 D85 +error(0.004005357180252827609) D64 D71 D76 D85 +error(0.001338700097173320998) D64 D73 D81 +error(0.003340032800510209492) D64 D73 D82 +error(0.002006705456917235505) D64 D73 D82 D83 +error(0.0006697986788568588423) D64 D73 D83 D85 +error(0.005995987492949031786) D64 D73 D85 +error(0.0006697986788568588423) D64 D74 D81 D82 +error(0.0006697986788568588423) D64 D74 D81 D83 D85 +error(0.0006697986788568588423) D64 D76 D82 +error(0.0006697986788568588423) D64 D76 D85 +error(0.0006697986788568588423) D64 D81 D82 +error(0.0006697986788568588423) D64 D81 D82 D83 +error(0.002673815958446297981) D64 D82 D83 D85 +error(0.002673815958446297981) D64 D82 D85 +error(0.01970848819953020456) D65 +error(0.004005357180252827609) D65 D66 +error(0.003340032800510209492) D65 D66 D68 +error(0.001338700097173320998) D65 D66 D68 D74 D75 D77 +error(0.001338700097173320998) D65 D66 D68 D74 D75 D86 +error(0.0006697986788568588423) D65 D66 D68 D74 D83 +error(0.001338700097173320998) D65 D66 D68 D74 D84 D86 +error(0.0006697986788568588423) D65 D66 D68 D75 D84 +error(0.0006697986788568588423) D65 D66 D68 D77 D83 D84 +error(0.001338700097173320998) D65 D66 D68 D77 D86 +error(0.001338700097173320998) D65 D66 D68 D83 D84 D86 +error(0.001338700097173320998) D65 D66 D70 +error(0.0006697986788568588423) D65 D66 D70 D74 D75 +error(0.0006697986788568588423) D65 D66 D70 D74 D75 D86 +error(0.0006697986788568588423) D65 D66 D70 D74 D84 +error(0.0006697986788568588423) D65 D66 D70 D74 D84 D86 +error(0.001338700097173320998) D65 D66 D70 D75 D84 +error(0.001338700097173320998) D65 D66 D74 D75 +error(0.0006697986788568588423) D65 D66 D74 D83 +error(0.001338700097173320998) D65 D66 D74 D84 +error(0.001338700097173320998) D65 D66 D75 D83 +error(0.001338700097173320998) D65 D66 D75 D84 +error(0.0006697986788568588423) D65 D66 D75 D84 D86 +error(0.0006697986788568588423) D65 D66 D77 D83 D84 +error(0.0006697986788568588423) D65 D66 D77 D86 +error(0.001338700097173320998) D65 D66 D83 D84 +error(0.001338700097173320998) D65 D66 D83 D84 D86 +error(0.002673815958446297981) D65 D67 +error(0.003340032800510209492) D65 D67 D68 +error(0.001338700097173320998) D65 D67 D68 D74 D76 D77 +error(0.001338700097173320998) D65 D67 D68 D74 D76 D86 +error(0.0006697986788568588423) D65 D67 D68 D74 D83 +error(0.001338700097173320998) D65 D67 D68 D74 D85 D86 +error(0.0006697986788568588423) D65 D67 D68 D76 D85 +error(0.0006697986788568588423) D65 D67 D68 D77 D83 D85 +error(0.001338700097173320998) D65 D67 D68 D77 D86 +error(0.001338700097173320998) D65 D67 D68 D83 D85 D86 +error(0.001338700097173320998) D65 D67 D71 +error(0.0006697986788568588423) D65 D67 D71 D73 D74 D76 +error(0.0006697986788568588423) D65 D67 D71 D73 D74 D85 +error(0.0006697986788568588423) D65 D67 D71 D74 D76 D86 +error(0.0006697986788568588423) D65 D67 D71 D74 D85 D86 +error(0.001338700097173320998) D65 D67 D71 D76 D85 +error(0.0006697986788568588423) D65 D67 D72 D73 D83 +error(0.0006697986788568588423) D65 D67 D72 D82 D83 +error(0.001338700097173320998) D65 D67 D73 D82 +error(0.0006697986788568588423) D65 D67 D73 D83 D85 +error(0.0006697986788568588423) D65 D67 D76 D82 D83 +error(0.0006697986788568588423) D65 D67 D76 D82 D85 D86 +error(0.0006697986788568588423) D65 D67 D77 D83 D85 +error(0.0006697986788568588423) D65 D67 D77 D86 +error(0.0006697986788568588423) D65 D67 D82 D83 D85 +error(0.001338700097173320998) D65 D67 D83 D85 D86 +error(0.001338700097173320998) D65 D68 +error(0.0006697986788568588423) D65 D68 D72 D74 +error(0.0006697986788568588423) D65 D68 D72 D83 +error(0.001338700097173320998) D65 D68 D74 D83 +error(0.0006697986788568588423) D65 D68 D74 D84 +error(0.0006697986788568588423) D65 D68 D83 D84 +error(0.0006697986788568588423) D65 D72 +error(0.004005357180252827609) D65 D72 D81 +error(0.0006697986788568588423) D65 D72 D83 +error(0.0006697986788568588423) D65 D74 D75 D77 +error(0.0006697986788568588423) D65 D74 D75 D86 +error(0.0006697986788568588423) D65 D74 D76 D77 +error(0.0006697986788568588423) D65 D74 D76 D86 +error(0.002006705456917235505) D65 D74 D81 +error(0.001338700097173320998) D65 D74 D81 D82 +error(0.002673815958446297981) D65 D74 D81 D83 D84 +error(0.002006705456917235505) D65 D74 D81 D83 D85 +error(0.005333333333333313206) D65 D74 D81 D86 +error(0.002673815958446297981) D65 D74 D83 +error(0.0006697986788568588423) D65 D74 D84 D86 +error(0.0006697986788568588423) D65 D74 D85 D86 +error(0.001338700097173320998) D65 D75 D83 +error(0.0006697986788568588423) D65 D75 D84 +error(0.0006697986788568588423) D65 D75 D84 D86 +error(0.0006697986788568588423) D65 D76 D82 D83 +error(0.0006697986788568588423) D65 D76 D82 D85 D86 +error(0.004005357180252827609) D65 D77 D86 +error(0.0006697986788568588423) D65 D81 +error(0.0006697986788568588423) D65 D81 D82 D83 +error(0.001338700097173320998) D65 D81 D83 +error(0.0006697986788568588423) D65 D82 D83 D85 +error(0.002006705456917235505) D65 D83 D84 +error(0.002673815958446297981) D65 D83 D84 D86 +error(0.002673815958446297981) D65 D83 D85 D86 +error(0.009295966703663446212) D66 +error(0.004005357180252827609) D66 D68 +error(0.003340032800510209492) D66 D68 D70 +error(0.001338700097173320998) D66 D68 D70 D75 D77 D79 +error(0.001338700097173320998) D66 D68 D70 D75 D77 D88 +error(0.0006697986788568588423) D66 D68 D70 D75 D84 +error(0.001338700097173320998) D66 D68 D70 D75 D86 D88 +error(0.0006697986788568588423) D66 D68 D70 D77 D86 +error(0.0006697986788568588423) D66 D68 D70 D79 D84 D86 +error(0.001338700097173320998) D66 D68 D70 D79 D88 +error(0.001338700097173320998) D66 D68 D70 D84 D86 D88 +error(0.0006697986788568588423) D66 D68 D74 D75 D77 +error(0.0006697986788568588423) D66 D68 D74 D75 D86 +error(0.001338700097173320998) D66 D68 D74 D83 +error(0.0006697986788568588423) D66 D68 D74 D84 +error(0.0006697986788568588423) D66 D68 D74 D84 D86 +error(0.0006697986788568588423) D66 D68 D75 D77 D88 +error(0.0006697986788568588423) D66 D68 D75 D86 D88 +error(0.0006697986788568588423) D66 D68 D77 D83 D84 +error(0.0006697986788568588423) D66 D68 D77 D83 D86 D88 +error(0.001338700097173320998) D66 D68 D77 D86 +error(0.0006697986788568588423) D66 D68 D79 D84 D86 +error(0.0006697986788568588423) D66 D68 D79 D88 +error(0.0006697986788568588423) D66 D68 D83 D84 +error(0.0006697986788568588423) D66 D68 D83 D84 D86 +error(0.001338700097173320998) D66 D68 D84 D86 D88 +error(0.006657753962803452177) D66 D70 +error(0.0006697986788568588423) D66 D70 D75 D77 D79 +error(0.0006697986788568588423) D66 D70 D75 D77 D88 +error(0.002006705456917235505) D66 D70 D75 D79 +error(0.0006697986788568588423) D66 D70 D75 D84 +error(0.002006705456917235505) D66 D70 D75 D88 +error(0.0006697986788568588423) D66 D70 D79 D84 +error(0.005333333333333313206) D66 D70 D79 D88 +error(0.001338700097173320998) D66 D70 D84 D88 +error(0.001338700097173320998) D66 D75 D83 +error(0.003340032800510209492) D66 D75 D84 +error(0.002006705456917235505) D66 D75 D84 D86 +error(0.0006697986788568588423) D66 D75 D86 D88 +error(0.005995987492949031786) D66 D75 D88 +error(0.0006697986788568588423) D66 D77 D83 D84 +error(0.0006697986788568588423) D66 D77 D83 D86 D88 +error(0.0006697986788568588423) D66 D79 D84 +error(0.0006697986788568588423) D66 D79 D88 +error(0.0006697986788568588423) D66 D83 D84 +error(0.0006697986788568588423) D66 D83 D84 D86 +error(0.002673815958446297981) D66 D84 D86 D88 +error(0.002673815958446297981) D66 D84 D88 +error(0.01582994014814808822) D67 +error(0.004005357180252827609) D67 D68 +error(0.003340032800510209492) D67 D68 D71 +error(0.001338700097173320998) D67 D68 D71 D76 D77 D80 +error(0.001338700097173320998) D67 D68 D71 D76 D77 D89 +error(0.0006697986788568588423) D67 D68 D71 D76 D85 +error(0.001338700097173320998) D67 D68 D71 D76 D86 D89 +error(0.0006697986788568588423) D67 D68 D71 D77 D86 +error(0.0006697986788568588423) D67 D68 D71 D80 D85 D86 +error(0.001338700097173320998) D67 D68 D71 D80 D89 +error(0.001338700097173320998) D67 D68 D71 D85 D86 D89 +error(0.0006697986788568588423) D67 D68 D73 D74 D85 +error(0.0006697986788568588423) D67 D68 D73 D83 D85 +error(0.0006697986788568588423) D67 D68 D74 D76 D77 +error(0.0006697986788568588423) D67 D68 D74 D76 D86 +error(0.001338700097173320998) D67 D68 D74 D83 +error(0.0006697986788568588423) D67 D68 D74 D85 D86 +error(0.0006697986788568588423) D67 D68 D76 D77 D89 +error(0.0006697986788568588423) D67 D68 D76 D86 D89 +error(0.0006697986788568588423) D67 D68 D77 D83 D85 +error(0.0006697986788568588423) D67 D68 D77 D83 D86 D89 +error(0.001338700097173320998) D67 D68 D77 D86 +error(0.0006697986788568588423) D67 D68 D80 D85 D86 +error(0.0006697986788568588423) D67 D68 D80 D89 +error(0.0006697986788568588423) D67 D68 D83 D85 D86 +error(0.001338700097173320998) D67 D68 D85 D86 D89 +error(0.005333333333333313206) D67 D69 +error(0.003340032800510209492) D67 D69 D71 +error(0.001338700097173320998) D67 D69 D71 D76 D78 D80 +error(0.001338700097173320998) D67 D69 D71 D76 D78 D89 +error(0.0006697986788568588423) D67 D69 D71 D76 D85 +error(0.001338700097173320998) D67 D69 D71 D76 D87 D89 +error(0.0006697986788568588423) D67 D69 D71 D78 D87 +error(0.0006697986788568588423) D67 D69 D71 D80 D85 D87 +error(0.001338700097173320998) D67 D69 D71 D80 D89 +error(0.001338700097173320998) D67 D69 D71 D85 D87 D89 +error(0.002006705456917235505) D67 D69 D76 D78 +error(0.0006697986788568588423) D67 D69 D76 D78 D89 +error(0.0006697986788568588423) D67 D69 D76 D85 +error(0.002006705456917235505) D67 D69 D76 D87 +error(0.0006697986788568588423) D67 D69 D76 D87 D89 +error(0.001338700097173320998) D67 D69 D78 D85 +error(0.002673815958446297981) D67 D69 D78 D87 +error(0.0006697986788568588423) D67 D69 D78 D87 D89 +error(0.0006697986788568588423) D67 D69 D80 D85 D87 +error(0.0006697986788568588423) D67 D69 D80 D89 +error(0.001338700097173320998) D67 D69 D85 D87 +error(0.001338700097173320998) D67 D69 D85 D87 D89 +error(0.005333333333333313206) D67 D71 +error(0.0006697986788568588423) D67 D71 D73 D76 +error(0.0006697986788568588423) D67 D71 D73 D85 +error(0.0006697986788568588423) D67 D71 D76 D77 D80 +error(0.0006697986788568588423) D67 D71 D76 D77 D89 +error(0.0006697986788568588423) D67 D71 D76 D78 D80 +error(0.0006697986788568588423) D67 D71 D76 D78 D89 +error(0.001338700097173320998) D67 D71 D76 D85 +error(0.0006697986788568588423) D67 D71 D76 D87 +error(0.004005357180252827609) D67 D71 D80 D89 +error(0.0006697986788568588423) D67 D71 D85 D87 +error(0.0006697986788568588423) D67 D72 D73 +error(0.0006697986788568588423) D67 D72 D82 +error(0.004005357180252827609) D67 D73 D82 +error(0.0006697986788568588423) D67 D73 D85 +error(0.002006705456917235505) D67 D76 D82 +error(0.001338700097173320998) D67 D76 D82 D83 +error(0.002006705456917235505) D67 D76 D82 D85 D86 +error(0.002673815958446297981) D67 D76 D82 D85 D87 +error(0.005333333333333313206) D67 D76 D82 D89 +error(0.002673815958446297981) D67 D76 D85 +error(0.0006697986788568588423) D67 D76 D86 D89 +error(0.0006697986788568588423) D67 D76 D87 D89 +error(0.0006697986788568588423) D67 D77 D83 D85 +error(0.0006697986788568588423) D67 D77 D83 D86 D89 +error(0.001338700097173320998) D67 D78 D85 +error(0.0006697986788568588423) D67 D78 D87 +error(0.0006697986788568588423) D67 D78 D87 D89 +error(0.0006697986788568588423) D67 D82 D83 D85 +error(0.001338700097173320998) D67 D82 D85 +error(0.0006697986788568588423) D67 D83 D85 D86 +error(0.002673815958446297981) D67 D85 D86 D89 +error(0.002006705456917235505) D67 D85 D87 +error(0.002673815958446297981) D67 D85 D87 D89 +error(0.01322685654994845347) D68 +error(0.004005357180252827609) D68 D70 +error(0.0006697986788568588423) D68 D70 D74 D75 D86 +error(0.0006697986788568588423) D68 D70 D74 D84 D86 +error(0.001338700097173320998) D68 D70 D75 D84 +error(0.0006697986788568588423) D68 D70 D75 D86 D88 +error(0.001338700097173320998) D68 D70 D77 D79 L0 +error(0.0006697986788568588423) D68 D70 D77 D86 +error(0.001338700097173320998) D68 D70 D77 D88 L0 +error(0.0006697986788568588423) D68 D70 D79 D84 D86 +error(0.0006697986788568588423) D68 D70 D79 D84 D88 L0 +error(0.0006697986788568588423) D68 D70 D79 D88 +error(0.0006697986788568588423) D68 D70 D84 D86 D88 +error(0.001338700097173320998) D68 D70 D86 D88 L0 +error(0.004005357180252827609) D68 D71 +error(0.0006697986788568588423) D68 D71 D74 D76 D86 +error(0.0006697986788568588423) D68 D71 D74 D85 D86 +error(0.001338700097173320998) D68 D71 D76 D85 +error(0.0006697986788568588423) D68 D71 D76 D86 D89 +error(0.001338700097173320998) D68 D71 D77 D80 L0 +error(0.0006697986788568588423) D68 D71 D77 D86 +error(0.001338700097173320998) D68 D71 D77 D89 L0 +error(0.0006697986788568588423) D68 D71 D80 D85 D86 +error(0.0006697986788568588423) D68 D71 D80 D85 D89 L0 +error(0.0006697986788568588423) D68 D71 D80 D89 +error(0.0006697986788568588423) D68 D71 D85 D86 D89 +error(0.001338700097173320998) D68 D71 D86 D89 L0 +error(0.0006697986788568588423) D68 D75 D77 D79 +error(0.0006697986788568588423) D68 D75 D77 D88 +error(0.0006697986788568588423) D68 D76 D77 D80 +error(0.0006697986788568588423) D68 D76 D77 D89 +error(0.0006697986788568588423) D68 D77 D79 L0 +error(0.0006697986788568588423) D68 D77 D80 L0 +error(0.001338700097173320998) D68 D77 D83 D84 +error(0.001338700097173320998) D68 D77 D83 D85 +error(0.002006705456917235505) D68 D77 D83 D86 D88 +error(0.002006705456917235505) D68 D77 D83 D86 D89 +error(0.005333333333333313206) D68 D77 D83 L0 +error(0.002673815958446297981) D68 D77 D86 +error(0.001338700097173320998) D68 D77 D88 L0 +error(0.001338700097173320998) D68 D77 D89 L0 +error(0.0006697986788568588423) D68 D79 D84 D86 +error(0.0006697986788568588423) D68 D79 D84 D88 L0 +error(0.001338700097173320998) D68 D79 D88 +error(0.0006697986788568588423) D68 D80 D85 D86 +error(0.0006697986788568588423) D68 D80 D85 D89 L0 +error(0.001338700097173320998) D68 D80 D89 +error(0.0006697986788568588423) D68 D83 D84 D86 +error(0.0006697986788568588423) D68 D83 D85 D86 +error(0.0006697986788568588423) D68 D84 D86 D88 +error(0.0006697986788568588423) D68 D85 D86 D89 +error(0.002673815958446297981) D68 D86 D88 L0 +error(0.002673815958446297981) D68 D86 D89 L0 +error(0.01518047719643240284) D69 +error(0.004005357180252827609) D69 D71 +error(0.001338700097173320998) D69 D71 D76 D85 +error(0.0006697986788568588423) D69 D71 D76 D87 +error(0.0006697986788568588423) D69 D71 D76 D87 D89 +error(0.001338700097173320998) D69 D71 D78 D80 L0 +error(0.0006697986788568588423) D69 D71 D78 D87 +error(0.001338700097173320998) D69 D71 D78 D89 L0 +error(0.0006697986788568588423) D69 D71 D80 D85 D87 +error(0.0006697986788568588423) D69 D71 D80 D85 D89 L0 +error(0.0006697986788568588423) D69 D71 D80 D89 +error(0.0006697986788568588423) D69 D71 D85 D87 +error(0.0006697986788568588423) D69 D71 D85 D87 D89 +error(0.001338700097173320998) D69 D71 D87 D89 L0 +error(0.0006697986788568588423) D69 D76 D78 D80 +error(0.0006697986788568588423) D69 D76 D78 D89 +error(0.0006697986788568588423) D69 D78 D80 L0 +error(0.001338700097173320998) D69 D78 D85 +error(0.004005357180252827609) D69 D78 D87 +error(0.002006705456917235505) D69 D78 D87 D89 +error(0.001338700097173320998) D69 D78 D89 L0 +error(0.007978628588222850399) D69 D78 L0 +error(0.0006697986788568588423) D69 D80 D85 D87 +error(0.0006697986788568588423) D69 D80 D85 D89 L0 +error(0.001338700097173320998) D69 D80 D89 +error(0.0006697986788568588423) D69 D85 D87 +error(0.0006697986788568588423) D69 D85 D87 D89 +error(0.002673815958446297981) D69 D87 D89 L0 +error(0.002673815958446297981) D69 D87 L0 +error(0.01518047719643240284) D70 +error(0.0006697986788568588423) D70 D74 D75 +error(0.0006697986788568588423) D70 D74 D84 +error(0.0006697986788568588423) D70 D75 D77 D88 +error(0.004005357180252827609) D70 D75 D84 +error(0.0006697986788568588423) D70 D75 D86 D88 +error(0.0006697986788568588423) D70 D75 D88 +error(0.0006697986788568588423) D70 D77 D79 L0 +error(0.001338700097173320998) D70 D77 D86 +error(0.001338700097173320998) D70 D77 D88 L0 +error(0.002006705456917235505) D70 D79 D84 +error(0.001338700097173320998) D70 D79 D84 D86 +error(0.004669790293214320931) D70 D79 D84 D88 L0 +error(0.003340032800510209492) D70 D79 D88 +error(0.002673815958446297981) D70 D79 L0 +error(0.0006697986788568588423) D70 D84 D86 D88 +error(0.001338700097173320998) D70 D84 D88 +error(0.001338700097173320998) D70 D86 D88 L0 +error(0.002673815958446297981) D70 D88 L0 +error(0.009295966703663446212) D71 +error(0.0006697986788568588423) D71 D76 D77 D89 +error(0.0006697986788568588423) D71 D76 D78 D89 +error(0.0006697986788568588423) D71 D76 D86 D89 +error(0.0006697986788568588423) D71 D76 D87 D89 +error(0.0006697986788568588423) D71 D77 D80 L0 +error(0.001338700097173320998) D71 D77 D86 +error(0.001338700097173320998) D71 D77 D89 L0 +error(0.0006697986788568588423) D71 D78 D80 L0 +error(0.001338700097173320998) D71 D78 D87 +error(0.001338700097173320998) D71 D78 D89 L0 +error(0.001338700097173320998) D71 D80 D85 D86 +error(0.001338700097173320998) D71 D80 D85 D87 +error(0.004005357180252827609) D71 D80 D85 D89 L0 +error(0.002673815958446297981) D71 D80 D89 +error(0.0006697986788568588423) D71 D85 D86 D89 +error(0.0006697986788568588423) D71 D85 D87 D89 +error(0.001338700097173320998) D71 D86 D89 L0 +error(0.001338700097173320998) D71 D87 D89 L0 +error(0.004669790293214320931) D72 +error(0.002673815958446297981) D72 D73 +error(0.003340032800510209492) D72 D73 D74 +error(0.001338700097173320998) D72 D73 D83 +error(0.002673815958446297981) D72 D74 +error(0.007978628588222850399) D72 D81 +error(0.002673815958446297981) D72 D81 D82 +error(0.001338700097173320998) D72 D82 +error(0.001338700097173320998) D72 D82 D83 +error(0.006657753962803452177) D72 D83 +error(0.003340032800510209492) D73 D74 D76 +error(0.001338700097173320998) D73 D74 D85 +error(0.002673815958446297981) D73 D76 +error(0.001338700097173320998) D73 D81 +error(0.007318633932043431753) D73 D82 +error(0.002006705456917235505) D73 D82 D83 +error(0.001338700097173320998) D73 D83 D85 +error(0.006657753962803452177) D73 D85 +error(0.002673815958446297981) D74 D75 +error(0.003340032800510209492) D74 D75 D77 +error(0.001338700097173320998) D74 D75 D86 +error(0.003340032800510209492) D74 D76 D77 +error(0.001338700097173320998) D74 D76 D86 +error(0.002006705456917235505) D74 D81 +error(0.001338700097173320998) D74 D81 D82 +error(0.002673815958446297981) D74 D81 D83 D84 +error(0.002006705456917235505) D74 D81 D83 D85 +error(0.005333333333333313206) D74 D81 D86 +error(0.007978628588222850399) D74 D83 +error(0.001338700097173320998) D74 D84 +error(0.001338700097173320998) D74 D84 D86 +error(0.001338700097173320998) D74 D85 D86 +error(0.003340032800510209492) D75 D77 D79 +error(0.001338700097173320998) D75 D77 D88 +error(0.003340032800510209492) D75 D79 +error(0.001338700097173320998) D75 D83 +error(0.007318633932043431753) D75 D84 +error(0.002006705456917235505) D75 D84 D86 +error(0.001338700097173320998) D75 D86 D88 +error(0.007318633932043431753) D75 D88 +error(0.003340032800510209492) D76 D77 D80 +error(0.001338700097173320998) D76 D77 D89 +error(0.003340032800510209492) D76 D78 +error(0.003340032800510209492) D76 D78 D80 +error(0.001338700097173320998) D76 D78 D89 +error(0.002006705456917235505) D76 D82 +error(0.001338700097173320998) D76 D82 D83 +error(0.002006705456917235505) D76 D82 D85 D86 +error(0.002673815958446297981) D76 D82 D85 D87 +error(0.005333333333333313206) D76 D82 D89 +error(0.007978628588222850399) D76 D85 +error(0.001338700097173320998) D76 D86 D89 +error(0.002006705456917235505) D76 D87 +error(0.001338700097173320998) D76 D87 D89 +error(0.002673815958446297981) D77 D79 L0 +error(0.002673815958446297981) D77 D80 L0 +error(0.001338700097173320998) D77 D83 D84 +error(0.001338700097173320998) D77 D83 D85 +error(0.002006705456917235505) D77 D83 D86 D88 +error(0.002006705456917235505) D77 D83 D86 D89 +error(0.005333333333333313206) D77 D83 L0 +error(0.007978628588222850399) D77 D86 +error(0.001338700097173320998) D77 D88 L0 +error(0.001338700097173320998) D77 D89 L0 +error(0.002673815958446297981) D78 D80 L0 +error(0.001338700097173320998) D78 D85 +error(0.01126536362635755656) D78 D87 +error(0.002006705456917235505) D78 D87 D89 +error(0.001338700097173320998) D78 D89 L0 +error(0.007978628588222850399) D78 L0 +error(0.002006705456917235505) D79 D84 +error(0.001338700097173320998) D79 D84 D86 +error(0.004669790293214320931) D79 D84 D88 L0 +error(0.007978628588222850399) D79 D88 +error(0.002673815958446297981) D79 L0 +error(0.001338700097173320998) D80 D85 D86 +error(0.001338700097173320998) D80 D85 D87 +error(0.004005357180252827609) D80 D85 D89 L0 +error(0.006657753962803452177) D80 D89 +error(0.002006705456917235505) D81 +error(0.002673815958446297981) D81 D82 +error(0.003340032800510209492) D81 D82 D83 +error(0.002673815958446297981) D81 D83 +error(0.003340032800510209492) D82 D83 D85 +error(0.002673815958446297981) D82 D85 +error(0.002673815958446297981) D83 D84 +error(0.003340032800510209492) D83 D84 D86 +error(0.003340032800510209492) D83 D85 D86 +error(0.003340032800510209492) D84 D86 D88 +error(0.002673815958446297981) D84 D88 +error(0.003340032800510209492) D85 D86 D89 +error(0.002673815958446297981) D85 D87 +error(0.003340032800510209492) D85 D87 D89 +error(0.002673815958446297981) D86 D88 L0 +error(0.002673815958446297981) D86 D89 L0 +error(0.002673815958446297981) D87 D89 L0 +error(0.002673815958446297981) D87 L0 +error(0.002673815958446297981) D88 L0 diff --git a/libs/qec/python/tests/test_color_code.py b/libs/qec/python/tests/test_color_code.py index 2cfd147db..1fc5dd38a 100644 --- a/libs/qec/python/tests/test_color_code.py +++ b/libs/qec/python/tests/test_color_code.py @@ -5,12 +5,17 @@ # This source code and the accompanying materials are made available under # # the terms of the Apache License 2.0 which accompanies this distribution. # # ============================================================================ # +import os + import pytest import numpy as np import cudaq import cudaq_qec as qec -from cudaq_qec.plugins.codes.color_code import ColorCodeGeometry +from cudaq_qec.plugins.codes import color_code as _color_code_mod +from cudaq_qec.plugins.codes.color_code import (ColorCodeGeometry, + _logical_pauli_words, + _plaquette_pauli_words) @pytest.fixture(scope="module", autouse=True) @@ -226,8 +231,6 @@ def test_print_structure_smoke(capsys): # --------------------------------------------------------------------------- # Pauli-word builders (plugin glue) # --------------------------------------------------------------------------- -from cudaq_qec.plugins.codes.color_code import (_logical_pauli_words, - _plaquette_pauli_words) def test_plaquette_pauli_words_d3_explicit(): @@ -240,9 +243,10 @@ def test_plaquette_pauli_words_d3_explicit(): def test_logical_pauli_words_d3_explicit(): - # d=3 bottom edge is qubits 4,5,6 — same as the Steane-style tail. + # Logical X is the all-data representative (X on all 7 data qubits); + # logical Z is the bottom edge (qubits 4,5,6 — the Steane-style tail). grid = ColorCodeGeometry(3) - assert _logical_pauli_words(grid) == ("IIIIXXX", "IIIIZZZ") + assert _logical_pauli_words(grid) == ("XXXXXXX", "IIIIZZZ") # --------------------------------------------------------------------------- @@ -309,8 +313,12 @@ def test_plugin_observables(d): Lx = code.get_observables_x() assert Lz.shape == (1, n) assert Lx.shape == (1, n) + # Z observable: bottom-edge weight-d representative. assert set(np.flatnonzero(Lz[0])) == set(grid.logical_qubits) - assert set(np.flatnonzero(Lx[0])) == set(grid.logical_qubits) + # X observable: all-data representative (all ones), matching the reference + # construction's all-data logical_observable. + assert np.all(Lx[0] == 1) + assert set(np.flatnonzero(Lx[0])) == set(range(n)) def test_plugin_stabilizers_list(): @@ -327,5 +335,512 @@ def test_plugin_stabilizers_list(): } +# --------------------------------------------------------------------------- +# Superdense CX-layer schedule (host-side builders) +# --------------------------------------------------------------------------- + + +def test_z_side_data_d3_truth_table(): + # Grid order: p0 green [0,1,2,3], p1 red [1,3,5,6], p2 blue [2,3,4,5]. + grid = ColorCodeGeometry(3) + assert grid.z_side_data() == [[0, 1, 3], [6], [3, 5]] + + +# --------------------------------------------------------------------------- +# Captured superdense stabilizer round +# --------------------------------------------------------------------------- + + +@pytest.fixture(scope="module", autouse=True) +def plugin_color_code(): + # Defensive re-registration: guarantee qec.get_code('color_code') resolves + # to this plugin's ColorCode for every test in this module, independent of + # collection order or of any other module registering the same name. + # Returns the plugin module for factory spying. + qec.code('color_code')(_color_code_mod.ColorCode) + return _color_code_mod + + +def test_make_stabilizer_round_returns_kernel(): + # The factory turns a captured flat schedule into a CUDA-Q kernel usable as + # the stabilizer_round operation encoding. + grid = ColorCodeGeometry(3) + k = _color_code_mod._make_stabilizer_round(grid.superdense_schedule()) + assert k is not None + assert hasattr(k, "name") # PyKernelDecorator + + +@pytest.mark.parametrize("d", [3, 5]) +def test_stabilizer_round_consumes_superdense_schedule(d, monkeypatch, + plugin_color_code): + # Gate-sequence check: the registered round must be the factory product + # built from *exactly* geometry.superdense_schedule() (the reference + # per-round gate sequence). A spy on the factory captures what + # ColorCode.__init__ hands it. + captured = {} + real_factory = _color_code_mod._make_stabilizer_round + + def spy(schedule_flat): + captured["schedule"] = list(schedule_flat) + return real_factory(schedule_flat) + + monkeypatch.setattr(_color_code_mod, "_make_stabilizer_round", spy) + # get_code re-runs ColorCode.__init__, which must build the round from the + # captured schedule (get_code returns the C++ Code wrapper, so we assert on + # the spied factory argument rather than on operation_encodings). + qec.get_code("color_code", distance=d) + grid = ColorCodeGeometry(d) + assert "schedule" in captured, \ + "ColorCode.__init__ did not build stabilizer_round via the factory" + assert captured["schedule"] == grid.superdense_schedule() + + +# --------------------------------------------------------------------------- +# Declared inlined-feedback matrices + plaquette-order assertion +# +# Record order [Z][X]: record k in [0,P) is plaquette k's Z-ancilla (a2); +# record P+k is plaquette k's X-ancilla (a1); numCols = 2P. The matrices are +# unit-tested on a directly instantiated ColorCode (the pure-Python getters), +# then exercised through the framework in the E2E block below. +# --------------------------------------------------------------------------- + + +def _fb_set(z_side_data, support): + """Reference F(S) = {a : |z_side_data[a] ∩ S| odd}, mirroring the module + helper but re-derived independently in the test.""" + s = set(support) + return [ + a for a, zd in enumerate(z_side_data) + if len(s.intersection(zd)) % 2 == 1 + ] + + +def test_get_inlined_feedback_d3_reference(): + code = _color_code_mod.ColorCode(distance=3) + fb = code.get_inlined_feedback() + assert fb.dtype == np.uint8 + assert fb.shape == (6, 6) + # Rows Z0,Z1,Z2,X0,X1,X2; columns [Z][X]. Diagonal entries are intentional + # (duplicate-record XOR cancellation in cudaq::detector). + expected = np.array([ + [1, 0, 1, 0, 0, 0], + [0, 1, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0], + ], + dtype=np.uint8) + np.testing.assert_array_equal(fb, expected) + + +def test_get_observable_inlined_feedback_z_d3_reference(): + code = _color_code_mod.ColorCode(distance=3) + obz = code.get_observable_inlined_feedback_z() + assert obz.dtype == np.uint8 + assert obz.shape == (1, 6) + np.testing.assert_array_equal( + obz, np.array([[0, 1, 1, 0, 0, 0]], dtype=np.uint8)) + + +def test_observable_inlined_feedback_x_absent(): + # The X-basis logical (logical X read from data measured in X) commutes with + # the schedule's X byproduct, so no observable feedback is needed. The getter + # is intentionally absent; the bridge maps the missing method to the empty + # default (verified as no-feedback by the deterministic X-basis E2E tests). + code = _color_code_mod.ColorCode(distance=3) + assert not hasattr(code, "get_observable_inlined_feedback_x") + + +@pytest.mark.parametrize("d", [3, 5, 7]) +def test_feedback_matrices_shape_dtype_and_x_block_zero(d): + code = _color_code_mod.ColorCode(distance=d) + P = code.grid.num_plaquettes + fb = code.get_inlined_feedback() + obz = code.get_observable_inlined_feedback_z() + assert fb.shape == (2 * P, 2 * P) and fb.dtype == np.uint8 + assert obz.shape == (1, 2 * P) and obz.dtype == np.uint8 + # X records (>= P) neither herald nor receive the byproduct. + assert not fb[P:, :].any() + assert not fb[:, P:].any() + assert not obz[:, P:].any() + + +def test_feedback_F_sets_d5_spot_check(): + # Brief's triple-verified d=5 cross-check of F(supp) per plaquette and + # F(logical), plus that the assembled matrices agree with F. + grid = ColorCodeGeometry(5) + zsd = grid.z_side_data() + expected_F = { + 0: [0, 2], + 1: [1, 4], + 2: [0, 2, 5], + 3: [3, 7], + 4: [1, 4, 8], + 5: [2, 5], + 6: [6], + 7: [3], + 8: [4], + } + for j, plaq in enumerate(grid.plaquettes): + assert _fb_set(zsd, plaq['data_qubits']) == expected_F[j] + assert _fb_set(zsd, grid.logical_qubits) == [5, 6, 7, 8] + + code = _color_code_mod.ColorCode(distance=5) + fb = code.get_inlined_feedback() + obz = code.get_observable_inlined_feedback_z() + for j in range(grid.num_plaquettes): + assert sorted(np.flatnonzero(fb[j]).tolist()) == expected_F[j] + assert sorted(np.flatnonzero(obz[0]).tolist()) == [5, 6, 7, 8] + + +@pytest.mark.parametrize("d", [3, 5, 7, 9]) +def test_plaquette_order_assertion_passes(d): + grid = ColorCodeGeometry(d) + # Does not raise for any supported distance. + _color_code_mod._assert_plaquette_order(grid.plaquettes) + mins = [min(p['data_qubits']) for p in grid.plaquettes] + assert all(a < b for a, b in zip(mins, mins[1:])) + + +def test_plaquette_order_assertion_rejects_bad_order(): + # Two plaquettes sharing a min data-qubit index (0) — not strictly + # increasing, so record k could not map to plaquette k. + bad = [{'data_qubits': [0, 1, 2, 3]}, {'data_qubits': [0, 2, 4, 5]}] + with pytest.raises(ValueError, match="strictly-increasing"): + _color_code_mod._assert_plaquette_order(bad) + + +# --------------------------------------------------------------------------- +# Framework-path E2E payoff (stim target) — the declared feedback makes the +# X-basis memory deterministic and the DEM/decode pipeline work in both bases. +# --------------------------------------------------------------------------- + + +@pytest.mark.parametrize("prep,basis,obs_getter,expected", [ + (qec.operation.prep0, 'z', 'get_observables_z', 0), + (qec.operation.prep1, 'z', 'get_observables_z', 1), + (qec.operation.prepp, 'x', 'get_observables_x', 0), + (qec.operation.prepm, 'x', 'get_observables_x', 1), +]) +@pytest.mark.parametrize("nRounds", [2, 4]) +def test_noiseless_memory_deterministic_both_bases(plugin_color_code, prep, + basis, obs_getter, expected, + nRounds): + code = qec.get_code('color_code', distance=3) + sample_fn = (qec.z_sample_memory_circuit + if basis == 'z' else qec.x_sample_memory_circuit) + syndromes, data = sample_fn(code, prep, 20, nRounds, cudaq.NoiseModel()) + # Noise-free: every detector is deterministic, so all syndromes vanish. + assert not np.any(syndromes) + L = getattr(code, obs_getter)() + logical = ((L @ data.T) % 2).flatten() + assert np.all(logical == expected) + + +def test_z_dem_from_memory_circuit_shapes(plugin_color_code): + code = qec.get_code('color_code', distance=3) + P = code.get_num_z_stabilizers() + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1) + nRounds = 4 + dem = qec.z_dem_from_memory_circuit(code, qec.operation.prep0, nRounds, + noise) + assert dem.detector_error_matrix.shape[0] == (nRounds + 1) * P + assert len(dem.error_rates) == dem.detector_error_matrix.shape[1] + assert dem.observables_flips_matrix.shape == ( + 1, dem.detector_error_matrix.shape[1]) + assert all(rate > 0 for rate in dem.error_rates) + # Detector rows line up column-for-column with sampled Z syndromes. + syndromes, _ = qec.z_sample_memory_circuit(code, qec.operation.prep0, 10, + nRounds, noise) + assert syndromes.shape[1] == dem.detector_error_matrix.shape[0] + + +def test_x_dem_from_memory_circuit_shapes(plugin_color_code): + code = qec.get_code('color_code', distance=3) + P = code.get_num_x_stabilizers() + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1) + nRounds = 3 + dem = qec.x_dem_from_memory_circuit(code, qec.operation.prepp, nRounds, + noise) + # X-basis keeps only the X-stabilizer detectors: (nRounds + 1) * P rows. + assert dem.detector_error_matrix.shape[0] == (nRounds + 1) * P + assert dem.detector_error_matrix.shape[1] > 0 + assert len(dem.error_rates) == dem.detector_error_matrix.shape[1] + syndromes, _ = qec.x_sample_memory_circuit(code, qec.operation.prepp, 10, + nRounds, noise) + assert syndromes.shape[1] == dem.detector_error_matrix.shape[0] + + +def test_noisy_sampling_shapes_and_activity(plugin_color_code): + code = qec.get_code('color_code', distance=3) + P = code.get_num_z_stabilizers() + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.05), 1) + nShots, nRounds = 100, 4 + syndromes, data = qec.z_sample_memory_circuit(code, qec.operation.prep0, + nShots, nRounds, noise) + assert syndromes.shape == (nShots, (nRounds + 1) * P) + assert data.shape == (nShots, code.get_num_data_qubits()) + assert np.any(syndromes) + + +def test_decoding_reduces_logical_errors_x_basis(plugin_color_code): + # Decode smoke in the X basis. The X basis has no observable feedback + # (absent get_observable_inlined_feedback_x), so Lx @ data IS the DEM + # observable and a valid ground truth. The Z-basis observable is the + # byproduct-corrected DEM observable whose feedback (herald) records + # sample_memory_circuit does not return, so a Z-basis truth from data alone + # would be wrong — the realtime-only "DEM crux". + cudaq.set_random_seed(13) + code = qec.get_code('color_code', distance=3) + Lx = code.get_observables_x() + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1) + nRounds, nShots = 6, 400 + + dem = qec.x_dem_from_memory_circuit(code, qec.operation.prepp, nRounds, + noise) + syndromes, data = qec.x_sample_memory_circuit(code, qec.operation.prepp, + nShots, nRounds, noise) + logical = ((Lx @ data.T) % 2).flatten().astype(np.uint8) + + decoder = qec.get_decoder('single_error_lut', dem.detector_error_matrix) + dr = decoder.decode_batch(np.asarray(syndromes, dtype=np.uint8)) + err_pred = np.asarray(dr.result, dtype=np.uint8) + predictions = ((dem.observables_flips_matrix @ err_pred.T) % 2).flatten() + + n_without = int(np.sum(logical)) + n_with = int(np.sum(predictions ^ logical)) + print(f"logical errors without decoding: {n_without}, with: {n_with}") + assert n_with < n_without + + +def test_declared_feedback_makes_x_path_deterministic(plugin_color_code): + # With the byproduct-correcting CX dropped from the round and no feedback + # declared, the X-basis (prepp) DEM was rejected with "non-deterministic + # detectors". With the feedback matrices declared it now builds — the flip + # from negative to positive control. + code = qec.get_code("color_code", distance=3) + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1) + dem = qec.x_dem_from_memory_circuit(code, qec.operation.prepp, 3, noise) + assert dem.detector_error_matrix.shape[0] > 0 + assert dem.detector_error_matrix.shape[1] > 0 + + +def test_z_path_never_raises(plugin_color_code): + # The Z-basis heralds are Z-ancilla records that are deterministically 0 + # in noiseless prep0, so the Z path was deterministic even with the bare + # (no-feedback) round and remains so with the feedback declared. + code = qec.get_code("color_code", distance=3) + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1) + dem = qec.z_dem_from_memory_circuit(code, qec.operation.prep0, 3, noise) + assert dem.detector_error_matrix.shape[0] > 0 + + +def test_undeclared_feedback_breaks_determinism(plugin_color_code): + # Retained bare-round negative control: a code that reuses the plugin's + # bare superdense round (via delegation) but declares NO feedback getters + # hits the non-deterministic-detector rejection on the X path, proving the + # declared matrices are load-bearing. (A plain ColorCode subclass cannot be used: + # qec.code() copies only the decorated class's own __dict__ and reparents + # to Code, dropping inherited methods — hence the delegation.) + @qec.code('color_code_bare_control') + class ColorCodeBareControl: + + def __init__(self, **kwargs): + qec.Code.__init__(self) + self._c = _color_code_mod.ColorCode(**kwargs) + self.stabilizers = self._c.stabilizers + self.pauli_observables = self._c.pauli_observables + self.operation_encodings = self._c.operation_encodings + + def get_num_data_qubits(self): + return self._c.get_num_data_qubits() + + def get_num_ancilla_x_qubits(self): + return self._c.get_num_ancilla_x_qubits() + + def get_num_ancilla_z_qubits(self): + return self._c.get_num_ancilla_z_qubits() + + def get_num_ancilla_qubits(self): + return self._c.get_num_ancilla_qubits() + + def get_num_x_stabilizers(self): + return self._c.get_num_x_stabilizers() + + def get_num_z_stabilizers(self): + return self._c.get_num_z_stabilizers() + + code = qec.get_code('color_code_bare_control', distance=3) + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1) + with pytest.raises(ValueError, match="non-deterministic detectors"): + qec.x_dem_from_memory_circuit(code, qec.operation.prepp, 3, noise) + + +# --------------------------------------------------------------------------- +# Golden oracle: framework DEM vs the reference superdense DEMs, +# d=5, rounds=5, DEPOLARIZE2(0.01) per schedule CX. +# +# The full (both-basis-detector) framework DEM comes from the non-directional +# qec.dem_from_memory_circuit: it keeps all 2*P*rounds detectors, matching the +# golden's layout. The directional z/x_dem_from_memory_circuit slice out the +# off-basis cross-round detectors ((rounds+1)*P rows) and so cannot be compared +# row-for-row against the full 90-detector golden. +# +# The reference files are the ALL-ROUNDS-NOISY convention (every stabilizer +# round noisy — physically stricter). They were generated by the reference +# superdense construction (superdense_memory kernel, cudaq.dem_from_kernel); +# the same generator byte-reproduces the reference construction's original +# perfect-final-round DEMs when its two noise guards (R > 1 and r < R - 1) are +# restored. Those perfect-final-round originals are retained outside the test +# suite. +# +# Under the all-rounds-noisy convention the framework DEM equals the reference +# mechanism-for-mechanism, including the observable-flip column, at bit-exact +# probabilities (0 diff, both bases, verified when the goldens were generated). +# This pins the plugin's schedule, [Z][X] record order, feedback matrices, the +# logical-X observable representative, and the detector-alignment permutation +# below as exact. A comparison against the perfect-final-round originals awaits +# a framework noiseless-final-round capability (memory_circuit noises every +# stabilizer round; there is no perfect-final-round knob). +# --------------------------------------------------------------------------- + +_DATA_DIR = os.path.join(os.path.dirname(__file__), "data") + + +def _merge_error_prob(p, q): + # Two independent error mechanisms with identical detector/observable + # support combine as p*(1-q) + q*(1-p). + return p + q - 2.0 * p * q + + +def _golden_signature(dem_text, stim_mod): + """Canonical {(detector-support, observable-support): merged prob} of a + stim DEM text. flattened() expands repeat/shift blocks; detector targets + across '^' decomposition separators are unioned (separators ignored), so + the signature is invariant to graphlike error decomposition.""" + sig = {} + for inst in stim_mod.DetectorErrorModel(dem_text).flattened(): + if inst.type != "error": + continue + prob = inst.args_copy()[0] + dets, obss = [], [] + for t in inst.targets_copy(): + if t.is_relative_detector_id(): + dets.append(t.val) + elif t.is_logical_observable_id(): + obss.append(t.val) + key = (tuple(sorted(dets)), tuple(sorted(obss))) + sig[key] = _merge_error_prob(sig[key], prob) if key in sig else prob + return sig + + +def _framework_detector_permutation(P, num_rounds): + """Framework detector index -> golden emission index. + + Both circuits emit P round-0 fixed detectors (prep basis), then num_rounds-1 + interior rounds each carrying a full [Z-block(P), X-block(P)] ancilla pair, + then P boundary detectors. memory_circuit.cpp emits each interior round + Z-block-first (the round returns mz([*ancz, *ancx]), so cross-round records + j < P are the Z ancillas); the reference superdense_memory kernel emits each + interior round X-block-first. Round-0 and boundary blocks are identical. So + the alignment swaps the two P-sized halves of every interior round and is the + identity elsewhere -- derived from the two emission orders, not fit to the + DEM contents.""" + total = 2 * P * num_rounds + perm = {} + for i in range(total): + if i < P or i >= total - P: + perm[i] = i + continue + local = i - P + rr = local // (2 * P) + within = local % (2 * P) + base = P + rr * (2 * P) + perm[i] = base + (within + P if within < P else within - P) + assert sorted(perm.values()) == list(range(total)) + return perm + + +def _framework_signature(dem, perm): + """Canonical {(detector-support, observable-support): merged prob} of a + framework detector_error_model, with detector indices mapped through perm.""" + dm = np.asarray(dem.detector_error_matrix, dtype=np.uint8) + obs = np.asarray(dem.observables_flips_matrix, dtype=np.uint8) + rates = np.asarray(dem.error_rates, dtype=float) + sig = {} + for c in range(dm.shape[1]): + dets = tuple(sorted(perm[int(r)] for r in np.flatnonzero(dm[:, c]))) + ob = tuple(np.flatnonzero(obs[:, c]).tolist()) + key = (dets, ob) + sig[key] = _merge_error_prob(sig[key], + rates[c]) if key in sig else rates[c] + return sig + + +@pytest.mark.parametrize("basis,prep", [("Z", qec.operation.prep0), + ("X", qec.operation.prepp)]) +def test_dem_matches_reference_golden(plugin_color_code, basis, prep): + """Framework DEM equals the reference superdense DEM, d=5, rounds=5. + + The goldens (superdense_golden_d5_r5_allnoisy_{Z,X}.dem) are the + ALL-ROUNDS-NOISY convention: every stabilizer round carries + DEPOLARIZE2(0.01) on each schedule CX (physically stricter than a perfect + final round). They were generated by the reference superdense construction; + that same generator byte-reproduces the reference perfect-final-round DEMs + (retained outside the test suite) when its two noise guards are restored, + so the goldens carry the reference construction exactly, only under the + stricter noise convention. d=5 is the smallest distance exercising every + structural element: bulk weight-6 plaquettes of all three colors plus every + boundary type. The comparison is exact -- same canonical merged signatures, + the observable-flip column included, bit-exact probability equality under + the structural detector permutation. A comparison against the + perfect-final-round originals awaits a framework noiseless-final-round + capability (memory_circuit noises every round).""" + stim_mod = pytest.importorskip("stim") + d, rounds = 5, 5 + code = qec.get_code('color_code', distance=d) + P = code.get_num_z_stabilizers() + noise = cudaq.NoiseModel() + noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1) + dem = qec.dem_from_memory_circuit(code, prep, rounds, noise) + perm = _framework_detector_permutation(P, rounds) + got = _framework_signature(dem, perm) + with open( + os.path.join( + _DATA_DIR, + f"superdense_golden_d{d}_r{rounds}_allnoisy_{basis}.dem")) as f: + golden_text = f.read() + # Belt-and-suspenders: the golden files carry a fixed number of error + # mechanisms (2957 Z / 2958 X); a mismatch means a corrupted or truncated + # golden, not a plugin regression. + n_mechanisms = sum( + 1 for inst in stim_mod.DetectorErrorModel(golden_text).flattened() + if inst.type == "error") + assert n_mechanisms == { + "Z": 2957, + "X": 2958 + }[basis], ( + f"golden file parsed {n_mechanisms} error mechanisms; expected " + f"{'2957' if basis == 'Z' else '2958'} — golden corrupted/truncated?") + ref = _golden_signature(golden_text, stim_mod) + assert set(ref) == set(got), ( + f"error-mechanism signatures differ: ref-only " + f"{sorted(set(ref) - set(got))[:5]}, ours-only " + f"{sorted(set(got) - set(ref))[:5]}") + # Bit-exact: the framework and generator DEMs agree to the last float bit + # (isolation max diff 0.0), so assert equality rather than a tolerance. + for k in ref: + assert ref[k] == got[k], ( + f"probability mismatch at {k}: ref={ref[k]}, ours={got[k]}") + + if __name__ == "__main__": pytest.main()