Is there a smart way to incorporate idling errors for a quantum error correction code using the open-source tool Stim (preferably using the tableau simulator)? I have perused the github website (https://github.com/quantumlib/Stim), as well as the associated paper on the topic (https://quantum-journal.org/papers/q-2021-07-06-497/), but to no avail.
No, there's no simple built-in way. You have to do it for yourself. This was an intentional design choice, which I will now attempt to justify because I do realize it's inconvenient.
Stim has no concept of an error model separate from the concept of a circuit. Errors are nothing more than a certain type of instruction that can appear in a circuit file. You can't tell Stim "please add depolarizing errors whenever [some complicated condition is met, such as idling during a measurement]". Instead, you tell Stim "now do
DEPOLARIZE1(0.001) 1 2 3, and then do ..., and then do ...". The way you add idling errors is to literally have error instructions, in the circuit, that implement the idling errors.
There are two "nice" ways to do this, I think:
Add noise parameters to your circuit generation code, and add noise instructions while generating the circuit. Stim's circuit generation code has a few very simple parameters for this, which I suppose contradicts my statement that stim has literally no concept of a noise model, but the circuit generation code is really just for getting started not for serious use.
Have a method that takes a noiseless circuit and noise parameters, then iterates over the circuit adding noise as appropriate. For example, that's what I did when analyzing the honeycomb code (source code). Basically: roll your own version of a noise model, specialized for your exact needs.
The motivating reason for the design choice to have noise instructions instead of noise models is that everyone has different ideas about how noise should behave. Here are some examples I've personally run into:
- Your two qubit gates don't have perfectly uniform depolarizing noise. They have biases towards certain Pauli pairs. So each two qubit gate needs 15 separate noise parameters (one for each non-identity Pauli pair).
- Different qubits on your chip have different T1 decay rates. So you need to specify an "idling multiplier" for every qubit you use.
- Different operations on your chip have different durations. Qubits idling during a measurement experience more depolarization than qubits idling during other operations. So you need to specify a "duration" for each operation, and a global "idling_per_duration" parameter.
- You're writing an error correction circuit, but you don't know how to handle corrections during logical initialization yet. Or during logical measurement. Or during a particularly tricky bit of code deformation right at the midway point. You disable noise during those times while you get the rest working. So every circuit layer needs a "disable noise" flag.
- Applying operations simultaneously can create crosstalk. So for every pair of operations that can occur simultaneously you may need a crosstalk parameter.
I hope you can see how unnecessarily complicated it would be to jumble all of these things together. And I also hope you can see there would always be just-one-more-thing to add; some other weird use case that wasn't accounted for. There's a natural tendency for the complexity of the rules to ratchet up and up and up until
**bam**: you're CSS, you're matplotlib, you're a tangle of spaghetti so dense people can spend a lifetime learning all the exceptions. Disgusting. Stim's design of "I just do exactly what you tell me" bypasses this rule-complexity-ratcheting issue. Each individual user can handle their individual complications, instead of needing to add one more strand to the community spaghetti stack.