Skip to content

Commit ea00f6e

Browse files
committed
add obs include paulis to all-ops circuit
1 parent 1b4fa0c commit ea00f6e

15 files changed

+312
-172
lines changed

src/stim/circuit/circuit.test.cc

+2
Original file line numberDiff line numberDiff line change
@@ -1807,12 +1807,14 @@ Circuit stim::generate_test_circuit_with_all_operations() {
18071807
DETECTOR(1, 2, 3) rec[-1]
18081808
OBSERVABLE_INCLUDE(0) rec[-1]
18091809
MPAD 0 1 0
1810+
OBSERVABLE_INCLUDE(1) Z2 Z3
18101811
TICK
18111812
18121813
# Inverted measurements.
18131814
MRX !0
18141815
MY !1
18151816
MZZ !2 3
1817+
OBSERVABLE_INCLUDE(1) rec[-1]
18161818
MYY !4 !5
18171819
MPP X6*!Y7*Z8
18181820
TICK

src/stim/cmd/command_m2d.cc

-14
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
// Copyright 2021 Google LLC
2-
//
3-
// Licensed under the Apache License, Version 2.0 (the "License");
4-
// you may not use this file except in compliance with the License.
5-
// You may obtain a copy of the License at
6-
//
7-
// http://www.apache.org/licenses/LICENSE-2.0
8-
//
9-
// Unless required by applicable law or agreed to in writing, software
10-
// distributed under the License is distributed on an "AS IS" BASIS,
11-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
// See the License for the specific language governing permissions and
13-
// limitations under the License.
14-
151
#include "stim/cmd/command_m2d.h"
162

173
#include "command_help.h"

src/stim/cmd/command_m2d.test.cc

+27
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,30 @@ TEST(command_m2d, m2d_obs_size_misalign_11_obs) {
154154
trim(std::string(1024, '0') + "\n"));
155155
ASSERT_EQ(tmp_obs.read_contents(), "00000000000\n");
156156
}
157+
158+
TEST(command_m2d, unphysical_observable_annotations) {
159+
RaiiTempNamedFile tmp_circuit(R"CIRCUIT(
160+
QUBIT_COORDS(0, 0) 0
161+
QUBIT_COORDS(1, 0) 1
162+
QUBIT_COORDS(0, 1) 2
163+
QUBIT_COORDS(1, 1) 3
164+
OBSERVABLE_INCLUDE(0) X0 X1
165+
OBSERVABLE_INCLUDE(1) Z0 Z2
166+
MPP X0*X1*X2*X3 Z0*Z1 Z2*Z3
167+
DEPOLARIZE1(0.001) 0 1 2 3
168+
MPP X0*X1*X2*X3 Z0*Z1 Z2*Z3
169+
DETECTOR rec[-1] rec[-4]
170+
DETECTOR rec[-2] rec[-5]
171+
DETECTOR rec[-3] rec[-6]
172+
OBSERVABLE_INCLUDE(0) X0 X1
173+
OBSERVABLE_INCLUDE(1) Z0 Z2
174+
)CIRCUIT");
175+
RaiiTempNamedFile tmp_obs;
176+
177+
ASSERT_EQ(
178+
trim(run_captured_stim_main(
179+
{"m2d", "--in_format=01", "--obs_out", tmp_obs.path.c_str(), "--circuit", tmp_circuit.path.c_str()},
180+
"000000\n100100\n000110\n")),
181+
trim("000\n000\n011\n"));
182+
ASSERT_EQ(tmp_obs.read_contents(), "00\n00\n00\n");
183+
}

src/stim/diagram/circuit_timeline_helper.cc

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
#include "stim/diagram/circuit_timeline_helper.h"
22

3-
#include "stim/diagram/diagram_util.h"
4-
53
using namespace stim;
64
using namespace stim_draw_internal;
75

8-
void CircuitTimelineHelper::skip_loop_iterations(CircuitTimelineLoopData loop_data, uint64_t skipped_reps) {
6+
void CircuitTimelineHelper::skip_loop_iterations(const CircuitTimelineLoopData &loop_data, uint64_t skipped_reps) {
97
if (loop_data.num_repetitions > 0) {
108
vec_pad_add_mul(cur_coord_shift, loop_data.shift_per_iteration, skipped_reps);
119
measure_offset += loop_data.measurements_per_iteration * skipped_reps;
@@ -95,6 +93,11 @@ GateTarget CircuitTimelineHelper::rec_to_qubit(const GateTarget &target) {
9593
}
9694

9795
GateTarget CircuitTimelineHelper::pick_pseudo_target_representing_measurements(const CircuitInstruction &op) {
96+
for (const auto &t : op.targets) {
97+
if (t.is_qubit_target() || t.is_pauli_target()) {
98+
return t;
99+
}
100+
}
98101
// First check if coordinates prefix-match a qubit's coordinates.
99102
if (!op.args.empty()) {
100103
auto coords = shifted_coordinates_in_workspace(op.args);

src/stim/diagram/circuit_timeline_helper.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ struct CircuitTimelineHelper {
6969

7070
stim::GateTarget rec_to_qubit(const stim::GateTarget &target);
7171
stim::GateTarget pick_pseudo_target_representing_measurements(const stim::CircuitInstruction &op);
72-
void skip_loop_iterations(CircuitTimelineLoopData loop_data, uint64_t skipped_reps);
72+
void skip_loop_iterations(const CircuitTimelineLoopData &loop_data, uint64_t skipped_reps);
7373
void do_record_measure_result(uint32_t target_qubit);
7474
void do_repeat_block(const stim::Circuit &circuit, const stim::CircuitInstruction &op);
7575
void do_next_operation(const stim::Circuit &circuit, const stim::CircuitInstruction &op);

src/stim/diagram/timeline/timeline_ascii_drawer.cc

+44-17
Original file line numberDiff line numberDiff line change
@@ -427,27 +427,54 @@ void DiagramTimelineAsciiDrawer::do_observable_include(const ResolvedTimelineOpe
427427
SpanRef<const GateTarget> rec_targets = op.targets;
428428
rec_targets.ptr_start++;
429429

430+
bool had_paulis = false;
431+
for (const auto &t : rec_targets) {
432+
if (t.is_pauli_target()) {
433+
had_paulis = true;
434+
std::stringstream ss;
435+
ss << "L" << (op.args.empty() ? 0 : op.args[0]) << "*=";
436+
ss << t.pauli_type();
437+
diagram.add_entry(
438+
AsciiDiagramEntry{
439+
{
440+
m2x(cur_moment),
441+
q2y(t.qubit_value()),
442+
GATE_ALIGNMENT_X,
443+
GATE_ALIGNMENT_Y,
444+
},
445+
ss.str(),
446+
});
447+
}
448+
}
449+
450+
bool had_rec = false;
430451
std::stringstream ss;
431-
ss << "OBSERVABLE_INCLUDE:L" << (op.args.empty() ? 0 : op.args[0]) << "*=";
432-
for (size_t k = 0; k < rec_targets.size(); k++) {
433-
if (k) {
434-
ss << "*";
452+
ss << "OBSERVABLE_INCLUDE:L" << (op.args.empty() ? 0 : op.args[0]);
453+
ss << "*=";
454+
for (const auto &t : rec_targets) {
455+
if (t.is_measurement_record_target()) {
456+
if (had_rec) {
457+
ss << "*";
458+
}
459+
had_rec = true;
460+
write_rec_index(ss, t.value());
435461
}
436-
write_rec_index(ss, rec_targets[k].value());
437462
}
438-
if (rec_targets.empty()) {
439-
ss.put('1');
463+
if (had_rec || !had_paulis) {
464+
if (rec_targets.empty()) {
465+
ss.put('1');
466+
}
467+
diagram.add_entry(
468+
AsciiDiagramEntry{
469+
{
470+
m2x(cur_moment),
471+
q2y(pseudo_target.qubit_value()),
472+
GATE_ALIGNMENT_X,
473+
GATE_ALIGNMENT_Y,
474+
},
475+
ss.str(),
476+
});
440477
}
441-
diagram.add_entry(
442-
AsciiDiagramEntry{
443-
{
444-
m2x(cur_moment),
445-
q2y(pseudo_target.qubit_value()),
446-
GATE_ALIGNMENT_X,
447-
GATE_ALIGNMENT_Y,
448-
},
449-
ss.str(),
450-
});
451478
}
452479

453480
void DiagramTimelineAsciiDrawer::do_resolved_operation(const ResolvedTimelineOperation &op) {

0 commit comments

Comments
 (0)