Building multi-qubit quantum channels

Does anyone have experience building multiqubit quantum channels? I can make a simple one with a single Krauss operator, but am having trouble defining a multiqubit channel with multiple Krauss operators. In this example, I’m applying a stochastic XX operator on qubits 1&2 and the identity on qubits 3&4.

This works:

channel = 
 QuantumChannel[
  Sqrt[0.5] QuantumTensorProduct[QuantumOperator["X", {1, 2}], 
    QuantumOperator["I", {3, 4}]]]

Now if I want to apply XX or YY with equal probability on qubits 1&2, I fail.

This doesn’t work:

channel = 
 QuantumChannel[{Sqrt[0.5]
     QuantumTensorProduct[QuantumOperator["X", {1, 2}], 
     QuantumOperator["I", {3, 4}]], 
   Sqrt[0.5]
     QuantumTensorProduct[QuantumOperator["Y", {1, 2}], 
     QuantumOperator["I", {3, 4}]]}]

I get this error message:

Thread::tdlen: Objects of unequal length in {4}->{1,2,3,4} cannot be combined.

Thanks in advance for any help.

Thank you for the speedy response. Upgrading to 13.3 from 13.0 and getting the latest paclet did the trick.

And thanks for the tips on optimizing the code.

Thanks!

That all works great, except I run into trouble when trying to apply the channels to qubits and 1 & 3 or qubits 2 & 4(for example). Seems like some default “ordering” behavior with channels that I don’t see with the QuantumOperators.

So, changing your code to

ops = {QuantumOperator["XX", {2, 3}], 
    QuantumOperator["YY", {2, 3}]} Sqrt[.5];
channel = QuantumChannel[ops]

applies the channel to qubits 2&3 just fine.

But similar code fails to apply the channel to qubits 2&4 and throws an error saying the Order size should be less than or equal to the number or qudits. Here is the code I tried for applying the channel to qubits 2&4.

ops = {QuantumOperator["XX", {2, 4}], 
    QuantumOperator["YY", {2, 4}]} Sqrt[.5];
channel = QuantumChannel[ops]

Note this same kind of code works fine for QuantumOperators, just not the Channels.

Hi David, it was a bug that we fixed. Please reinstall the paclet from dev link, and check. Let’s know if any issue.

Cool, I have it working now after the bug fix.

This isn’t really a bug, as I have found a work around, but thought I’d bring it up as a potential upgrade.

I’ve noticed that composing channels seems to get bogged down fairly quickly compared to composing quantum operators. For context, I’ve constructed a 2-qubit depolarizing channels to apply along with each two-qubit gate in my circuit.

   TQDepol[\[Epsilon]_] := 
  Sqrt[\[Epsilon]/
   15.0] {QuantumOperator["IX"], QuantumOperator["IY"], 
    QuantumOperator["IZ"], QuantumOperator["XI"], 
    QuantumOperator["XX"], QuantumOperator["XY"], 
    QuantumOperator["XZ"], QuantumOperator["YI"], 
    QuantumOperator["YX"], QuantumOperator["YY"], 
    QuantumOperator["YZ"], QuantumOperator["ZI"], 
    QuantumOperator["ZX"], 
    Sqrt[\[Epsilon]/15.0] QuantumOperator["ZY"], 
    QuantumOperator["ZZ"], 
    Sqrt[1 - \[Epsilon]]/Sqrt[\[Epsilon]/15.0] QuantumOperator["II"]};

TQDepolChannel[\[Epsilon]_, i_, j_] := 
 QuantumChannel[TQDepol[\[Epsilon]], {i, j}]

I can compose a couple of these maps, like this works just fine:

TQDepolChannel[\[Epsilon], 1, 2]@TQDepolChannel[\[Epsilon], 3, 4]

But the calculation quickly bogs down if I try to compose 3 or more of these channels. My work around is to apply the channels to a state. For example, this composition takes a very long time to evaluate,

TQDepolChannel[\[Epsilon], 1, 2]@ TQDepolChannel[\[Epsilon], 1, 2]@TQDepolChannel[\[Epsilon], 3, 4]

But this evaluates pretty quickly

TQDepolChannel[\[Epsilon], 1, 2]@ TQDepolChannel[\[Epsilon], 1, 2]@TQDepolChannel[\[Epsilon], 3, 4]@QuantumState["0000"]

While the second option is fast, it would sometimes be better to calculate the map for an arbitrary initial state. Maybe the slowdown comes from dealing with super-operators that act on density matrices and perhaps moving to the Liouville representation where the density matrix is vectorized will help - just speculating.

Anyway, thank you for the help.

Good point. That was due to calculating some properties in the summary box (here: TracePreservingQ) which was done inefficiently. Please reinstall the paclet; your example should not be bog down now.

Wonderful, everything is working beautifully now.

Well, maybe I spoke too soon. There does seem to be an improvement, but it seems to only buy me a factor of 2 as I still run into basically the same problem. Before, I could only compose 2 the channels defined above, and adding a third bogged the calculation down. Now I can compose 4 channels, but adding a 5th bogs things down again.

Hi Mads,

Not sure if you saw my last comment, but I’m basically finding that even relatively simple calculations are unworkable and hoping there might be some significant speed ups to be had - either on my end or on Wolframs end.

I’m attaching my notebook that shows what I’m doing. It’s only a 1-dimensional 4-qubit circuit with nearest neighbor interactions with periodic boundary conditions, and is designed to simulate a transverse field Ising model. If you run the notebook, I think you’ll find that the noiseless circuit can be computed just fine, but including the noise channels still bogs things down very quickly (basically after a single Trotter step).

Thank you for any help,
Dave

Channel compositions like EvenNoise@OddNoise@EvenNoise cumulatively increase underlying “trace” dimensionality. Just take a look at TQStep["Operator"]; its output has four 16-dimensional trace qudits, and the tensor already takes up 400Mb of memory (ByteCount[TQStep]). If you compose another channel, it will multiply it 256-fold(!), which is pretty much fatal on a commonplace computer.
Instead, consider making a circuit with individual elements QuantumCircuitOperator[{EvenNoise, OddNoise, EvenNoise}]; applying it to a state would result in a more efficient contraction of underlying tensor indices.

YES! That did it…THANK YOU!