#!/usr/bin/env python # coding: utf-8 # In[1]: import qutip from qutip.qinstrument import ( QInstrument, basis_measurement, pauli_measurement ) # ## Basics of instruments # In[2]: H = qutip.operations.hadamard_transform() # In[3]: ket_plus = H * qutip.basis(2, 0) # In[4]: z_instrument = basis_measurement(2) z_instrument # In[5]: z_instrument.sample(ket_plus) # In[6]: (H * z_instrument)(ket_plus) # ## Combining instruments # In[7]: z_instrument * z_instrument # In[8]: qutip.tensor([z_instrument] * 2) # In[9]: qutip.tensor(z_instrument.with_finite_visibility(0.95) ** 2, z_instrument) # ## Eliminating impossible outcomes # In[10]: z_instrument * z_instrument # In[11]: z_instrument.with_finite_visibility(0.95) ** 2 # ## Arbitrary dims # In[12]: basis_measurement(3) # ## Incomplete instruments # In[13]: qutip.QInstrument(qutip.projection(4, 0, 0)).complete() # In[14]: qutip.QInstrument(qutip.projection(4, 0, 0)).complete().reindex() # ## Arbitrary outcome labels # In[15]: pauli_measurement("ZZ") * pauli_measurement("XX") # In[16]: (pauli_measurement("ZZ") * pauli_measurement("XX")) ** 2 # In[17]: ( pauli_measurement("ZZ") * pauli_measurement("XX") ).with_finite_visibility(0.95) ** 2 # When using custom output labels, you can specify sequences of outcomes with `,` and parallel outcomes with `;`. Integers in strings are automatically converted, but other strings are preserved. # In[18]: QInstrument({ '0, 1, 2; 4, ⊥': qutip.projection(4, 0, 0) }) # For more complicated labels, `Seq` and `Par` can also be used directly. For example, the string `'0, 1, 2; 4, ⊥'` can also be written more explicitly as `Seq(Par(Seq(0, 1, 2), Seq(4, '⊥')),)`. # In[19]: from qutip.qinstrument import Seq, Par # In[20]: QInstrument({ Seq(Par(Seq(0, 1, 2), Seq(4, '⊥')),): qutip.projection(4, 0, 0), Seq(Par(Seq(0, 1, 2), Seq(Par('A', 'B'), 'C')),): qutip.projection(4, 1, 1) }) # ## Nonselective processes # In[21]: ins = ( pauli_measurement("ZZ") * pauli_measurement("XX") ).with_finite_visibility(0.95) ** 2 # In[22]: ins.nonselective_process # ## Checking CP/TP/HP # In[23]: ins.iscptp # In[24]: ins.ishp # In[25]: ins.istp # In[26]: ins.iscp # ## Operator overloading # In[27]: z_instrument & z_instrument.with_finite_visibility(0.95) # In[28]: z_instrument ^ 3 # ## Conditional processes # In[29]: reset = z_instrument.if_({ 1: qutip.to_super(qutip.sigmax()) }) reset # In[30]: reset.nonselective_process # In[31]: z_instrument.if_({ 1: qutip.QInstrument(qutip.to_super(qutip.sigmax())) }) # In[32]: V = ( (qutip.qeye(2) & qutip.qip.operations.cnot()) * (qutip.qeye(2) & qutip.qip.operations.hadamard_transform() & qutip.qeye(2)) * (qutip.qeye(2) & qutip.basis(2, 0) & qutip.basis(2, 0)) ) prepare_bell = qutip.sprepost(V, V.dag()) # In[33]: prepare_bell # In[34]: prepare_bell(qutip.basis(2, 0)).ptrace([0]) # In[35]: prepare_bell(qutip.basis(2, 0)).ptrace([1, 2]) # In[36]: bell_measurement = pauli_measurement("ZZ") * pauli_measurement("XX") # In[37]: bell_measurement # In[38]: teleport_wo_correction = ( (bell_measurement & qutip.to_super(qutip.qeye(2))) * prepare_bell ) teleport_wo_correction # In[39]: teleport = teleport_wo_correction.if_({ qutip.Seq("XX", "ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.qeye(2)), qutip.Seq("-XX", "ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.sigmaz()), qutip.Seq("XX", "-ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.sigmax()), qutip.Seq("-XX", "-ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.sigmay()), }) # In[40]: teleport.nonselective_process(qutip.basis(2, 0)).ptrace([2]) # In[41]: teleport.nonselective_process(qutip.basis(2, 1)).ptrace([2]) # In[42]: teleport.nonselective_process(qutip.qip.operations.hadamard_transform() * qutip.basis(2, 0)).ptrace([2]) # In[43]: teleport_wo_correction = ( (bell_measurement.with_finite_visibility(0.95) & qutip.to_super(qutip.qeye(2))) * prepare_bell ) # In[44]: teleport = teleport_wo_correction.if_({ qutip.Seq("XX", "ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.qeye(2)), qutip.Seq("-XX", "ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.sigmaz()), qutip.Seq("XX", "-ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.sigmax()), qutip.Seq("-XX", "-ZZ"): qutip.to_super((qutip.qeye(2) ^ 2) & qutip.sigmay()), }) # In[45]: teleport.nonselective_process(qutip.qip.operations.hadamard_transform() * qutip.basis(2, 0)).ptrace([2]) # In[ ]: