mirror of https://github.com/Qiskit/qiskit-aer.git
1705 lines
49 KiB
Python
1705 lines
49 KiB
Python
# This code is part of Qiskit.
|
|
#
|
|
# (C) Copyright IBM 2018, 2019.
|
|
#
|
|
# This code is licensed under the Apache License, Version 2.0. You may
|
|
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
|
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
|
#
|
|
# Any modifications or derivative works of this code must retain this
|
|
# copyright notice, and modified files need to carry a notice indicating
|
|
# that they have been altered from the originals.
|
|
"""
|
|
Test circuits and reference outputs for non-Clifford gate instructions.
|
|
"""
|
|
|
|
import numpy as np
|
|
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
|
|
|
|
# ==========================================================================
|
|
# T-gate
|
|
# ==========================================================================
|
|
|
|
|
|
def t_gate_circuits_deterministic(final_measure=True):
|
|
"""T-gate test circuits with deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(1)
|
|
if final_measure:
|
|
cr = ClassicalRegister(1)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# T
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.t(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# T.X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr)
|
|
circuit.barrier(qr)
|
|
circuit.t(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def t_gate_counts_deterministic(shots, hex_counts=True):
|
|
"""T-gate circuits reference counts."""
|
|
targets = []
|
|
if hex_counts:
|
|
# T
|
|
targets.append({"0x0": shots})
|
|
# T.X
|
|
targets.append({"0x1": shots})
|
|
else:
|
|
# T
|
|
targets.append({"0": shots})
|
|
# T.X
|
|
targets.append({"1": shots})
|
|
return targets
|
|
|
|
|
|
def t_gate_statevector_deterministic():
|
|
"""T-gate circuits reference statevectors."""
|
|
targets = []
|
|
# T
|
|
targets.append(np.array([1, 0]))
|
|
# T.X
|
|
targets.append(np.array([0, 1 + 1j]) / np.sqrt(2))
|
|
return targets
|
|
|
|
|
|
def t_gate_unitary_deterministic():
|
|
"""T-gate circuits reference unitaries."""
|
|
targets = []
|
|
# T
|
|
targets.append(np.diag([1, (1 + 1j) / np.sqrt(2)]))
|
|
# T.X
|
|
targets.append(np.array([[0, 1], [(1 + 1j) / np.sqrt(2), 0]]))
|
|
return targets
|
|
|
|
|
|
def t_gate_circuits_nondeterministic(final_measure=True):
|
|
"""T-gate test circuits with non-deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(1)
|
|
if final_measure:
|
|
cr = ClassicalRegister(1)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# T.H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr)
|
|
circuit.barrier(qr)
|
|
circuit.t(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# X.T.H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr)
|
|
circuit.barrier(qr)
|
|
circuit.t(qr)
|
|
circuit.barrier(qr)
|
|
circuit.x(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H.T.T.H = H.S.H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr)
|
|
circuit.barrier(qr)
|
|
circuit.t(qr)
|
|
circuit.barrier(qr)
|
|
circuit.t(qr)
|
|
circuit.barrier(qr)
|
|
circuit.h(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
return circuits
|
|
|
|
|
|
def t_gate_counts_nondeterministic(shots, hex_counts=True):
|
|
"""T-gate circuits reference counts."""
|
|
targets = []
|
|
if hex_counts:
|
|
# T.H
|
|
targets.append({"0x0": shots / 2, "0x1": shots / 2})
|
|
# X.T.H
|
|
targets.append({"0x0": shots / 2, "0x1": shots / 2})
|
|
# H.T.T.H = H.S.H
|
|
targets.append({"0x0": shots / 2, "0x1": shots / 2})
|
|
else:
|
|
# T.H
|
|
targets.append({"0": shots / 2, "1": shots / 2})
|
|
# X.T.H
|
|
targets.append({"0": shots / 2, "1": shots / 2})
|
|
# H.T.T.H = H.S.H
|
|
targets.append({"0": shots / 2, "1": shots / 2})
|
|
return targets
|
|
|
|
|
|
def t_gate_statevector_nondeterministic():
|
|
"""T-gate circuits reference statevectors."""
|
|
targets = []
|
|
# T.H
|
|
targets.append(np.array([1 / np.sqrt(2), 0.5 + 0.5j]))
|
|
# X.T.H
|
|
targets.append(np.array([0.5 + 0.5j, 1 / np.sqrt(2)]))
|
|
# H.T.T.H = H.S.H
|
|
targets.append(np.array([1 + 1j, 1 - 1j]) / 2)
|
|
return targets
|
|
|
|
|
|
def t_gate_unitary_nondeterministic():
|
|
"""T-gate circuits reference unitaries."""
|
|
targets = []
|
|
# T.H
|
|
targets.append(np.array([[1 / np.sqrt(2), 1 / np.sqrt(2)], [0.5 + 0.5j, -0.5 - 0.5j]]))
|
|
# X.T.H
|
|
targets.append(np.array([[0.5 + 0.5j, -0.5 - 0.5j], [1 / np.sqrt(2), 1 / np.sqrt(2)]]))
|
|
# H.T.T.H = H.S.H
|
|
targets.append(np.array([[1 + 1j, 1 - 1j], [1 - 1j, 1 + 1j]]) / 2)
|
|
return targets
|
|
|
|
|
|
# ==========================================================================
|
|
# T^dagger-gate
|
|
# ==========================================================================
|
|
|
|
|
|
def tdg_gate_circuits_deterministic(final_measure=True):
|
|
"""Tdg-gate test circuits with deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(1)
|
|
if final_measure:
|
|
cr = ClassicalRegister(1)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# Tdg
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.tdg(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H.Tdg.T.H = I
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr)
|
|
circuit.barrier(qr)
|
|
circuit.t(qr)
|
|
circuit.barrier(qr)
|
|
circuit.tdg(qr)
|
|
circuit.barrier(qr)
|
|
circuit.h(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def tdg_gate_counts_deterministic(shots, hex_counts=True):
|
|
"""Sdg-gate circuits reference counts."""
|
|
targets = []
|
|
if hex_counts:
|
|
# Tdg
|
|
targets.append({"0x0": shots})
|
|
# H.Tdg.T.H = I
|
|
targets.append({"0x0": shots})
|
|
else:
|
|
# Tdg
|
|
targets.append({"0": shots})
|
|
# H.Tdg.T.H = I
|
|
targets.append({"0": shots})
|
|
return targets
|
|
|
|
|
|
def tdg_gate_statevector_deterministic():
|
|
"""Sdg-gate circuits reference statevectors."""
|
|
targets = []
|
|
# Tdg
|
|
targets.append(np.array([1, 0]))
|
|
# H.Tdg.T.H = I
|
|
targets.append(np.array([1, 0]))
|
|
return targets
|
|
|
|
|
|
def tdg_gate_unitary_deterministic():
|
|
"""Tdg-gate circuits reference unitaries."""
|
|
targets = []
|
|
# Tdg
|
|
targets.append(np.diag([1, (1 - 1j) / np.sqrt(2)]))
|
|
# H.Tdg.T.H = I
|
|
targets.append(np.eye(2))
|
|
return targets
|
|
|
|
|
|
def tdg_gate_circuits_nondeterministic(final_measure=True):
|
|
"""Tdg-gate test circuits with non-deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(1)
|
|
if final_measure:
|
|
cr = ClassicalRegister(1)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# Tdg.H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr)
|
|
circuit.barrier(qr)
|
|
circuit.tdg(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# X.Tdg.H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr)
|
|
circuit.barrier(qr)
|
|
circuit.tdg(qr)
|
|
circuit.barrier(qr)
|
|
circuit.x(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H.Tdg.Tdg.H = H.Sdg.H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr)
|
|
circuit.barrier(qr)
|
|
circuit.tdg(qr)
|
|
circuit.barrier(qr)
|
|
circuit.tdg(qr)
|
|
circuit.barrier(qr)
|
|
circuit.h(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def tdg_gate_counts_nondeterministic(shots, hex_counts=True):
|
|
"""Tdg-gate circuits reference counts."""
|
|
targets = []
|
|
if hex_counts:
|
|
# Tdg.H
|
|
targets.append({"0x0": shots / 2, "0x1": shots / 2})
|
|
# X.Tdg.H
|
|
targets.append({"0x0": shots / 2, "0x1": shots / 2})
|
|
# H.Tdg.Tdg.H = H.Sdg.H
|
|
targets.append({"0x0": shots / 2, "0x1": shots / 2})
|
|
else:
|
|
# Tdg.H
|
|
targets.append({"0": shots / 2, "1": shots / 2})
|
|
# X.Tdg.H
|
|
targets.append({"0": shots / 2, "1": shots / 2})
|
|
# H.Tdg.Tdg.H = H.Sdg.H
|
|
targets.append({"0": shots / 2, "1": shots / 2})
|
|
return targets
|
|
|
|
|
|
def tdg_gate_statevector_nondeterministic():
|
|
"""Tdg-gate circuits reference statevectors."""
|
|
targets = []
|
|
# Tdg.H
|
|
targets.append(np.array([1 / np.sqrt(2), 0.5 - 0.5j]))
|
|
# X.Tdg.H
|
|
targets.append(np.array([0.5 - 0.5j, 1 / np.sqrt(2)]))
|
|
# H.Tdg.Tdg.H = H.Sdg.H
|
|
targets.append(np.array([1 - 1j, 1 + 1j]) / 2)
|
|
return targets
|
|
|
|
|
|
def tdg_gate_unitary_nondeterministic():
|
|
"""Tdg-gate circuits reference unitaries."""
|
|
targets = []
|
|
# Tdg.H
|
|
targets.append(np.array([[1 / np.sqrt(2), 1 / np.sqrt(2)], [0.5 - 0.5j, -0.5 + 0.5j]]))
|
|
# X.Tdg.H
|
|
targets.append(np.array([[0.5 - 0.5j, -0.5 + 0.5j], [1 / np.sqrt(2), 1 / np.sqrt(2)]]))
|
|
# H.Tdg.Tdg.H = H.Sdg.H
|
|
targets.append(np.array([[1 - 1j, 1 + 1j], [1 + 1j, 1 - 1j]]) / 2)
|
|
return targets
|
|
|
|
|
|
# ==========================================================================
|
|
# CCX-gate
|
|
# ==========================================================================
|
|
|
|
|
|
def ccx_gate_circuits_deterministic(final_measure=True):
|
|
"""CCX-gate test circuits with deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(3)
|
|
if final_measure:
|
|
cr = ClassicalRegister(3)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# CCX(0,1,2)
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.ccx(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# (I^X^X).CCX(0,1,2).(I^X^X) -> |100>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.ccx(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[0])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CCX(2,1,0)
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.ccx(qr[2], qr[1], qr[0])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# (X^X^I).CCX(2,1,0).(X^X^I) -> |001>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.ccx(qr[2], qr[1], qr[0])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def ccx_gate_counts_deterministic(shots, hex_counts=True):
|
|
"""CCX-gate circuits reference counts."""
|
|
targets = []
|
|
if hex_counts:
|
|
# CCX(0,1,2)
|
|
targets.append({"0x0": shots})
|
|
# (I^X^X).CCX(0,1,2).(I^X^X) -> |100>
|
|
targets.append({"0x4": shots})
|
|
# CCX(2,1,0)
|
|
targets.append({"0x0": shots})
|
|
# (X^X^I).CCX(2,1,0).(X^X^I) -> |001>
|
|
targets.append({"0x1": shots})
|
|
else:
|
|
# CCX(0,1,2)
|
|
targets.append({"000": shots})
|
|
# (I^X^X).CCX(0,1,2).(I^X^X) -> |100>
|
|
targets.append({"000": shots})
|
|
# CCX(2,1,0)
|
|
targets.append({"000": shots})
|
|
# (X^X^I).CCX(2,1,0).(X^X^I) -> |001>
|
|
targets.append({"001": shots})
|
|
return targets
|
|
|
|
|
|
def ccx_gate_statevector_deterministic():
|
|
"""CCX-gate circuits reference statevectors."""
|
|
targets = []
|
|
zero_state = np.array([1, 0, 0, 0, 0, 0, 0, 0])
|
|
# CCX(0,1,2)
|
|
targets.append(zero_state)
|
|
# (I^X^X).CCX(0,1,2).(I^X^X) -> |100>
|
|
targets.append(np.array([0, 0, 0, 0, 1, 0, 0, 0]))
|
|
# CCX(2,1,0)
|
|
targets.append(zero_state)
|
|
# (X^X^I).CCX(2,1,0).(X^X^I) -> |001>
|
|
targets.append(np.array([0, 1, 0, 0, 0, 0, 0, 0]))
|
|
return targets
|
|
|
|
|
|
def ccx_gate_unitary_deterministic():
|
|
"""CCX-gate circuits reference unitaries."""
|
|
targets = []
|
|
|
|
# CCX(0,1,2)
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# (I^X^X).CCX(0,1,2).(I^X^X) -> |100>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
]
|
|
)
|
|
)
|
|
# CCX(2,1,0)
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
]
|
|
)
|
|
)
|
|
# (X^X^I).CCX(2,1,0).(X^X^I) -> |001>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
]
|
|
)
|
|
)
|
|
return targets
|
|
|
|
|
|
def ccx_gate_circuits_nondeterministic(final_measure=True):
|
|
"""CCX-gate test circuits with non-deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(3)
|
|
if final_measure:
|
|
cr = ClassicalRegister(3)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# (I^X^I).CCX(0,1,2).(I^X^H) -> |000> + |101>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[0])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.ccx(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# (X^I^I).CCX(2,1,0).(X^H^I) -> |000> + |011>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.ccx(qr[2], qr[1], qr[0])
|
|
circuit.barrier(qr)
|
|
circuit.x(qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def ccx_gate_counts_nondeterministic(shots, hex_counts=True):
|
|
"""CCX-gate circuits reference counts."""
|
|
targets = []
|
|
if hex_counts:
|
|
# (I^X^I).CCX(0,1,2).(I^X^H) -> |000> + |101>
|
|
targets.append({"0x0": shots / 2, "0x5": shots / 2})
|
|
# (X^I^I).CCX(2,1,0).(X^H^I) -> |000> + |011>
|
|
targets.append({"0x0": shots / 2, "0x3": shots / 2})
|
|
else:
|
|
# (I^X^I).CCX(0,1,2).(I^X^H) -> |000> + |101>
|
|
targets.append({"000": shots / 2, "101": shots / 2})
|
|
# (X^I^I).CCX(2,1,0).(X^H^I) -> |000> + |011>
|
|
targets.append({"000": shots / 2, "011": shots / 2})
|
|
return targets
|
|
|
|
|
|
def ccx_gate_statevector_nondeterministic():
|
|
"""CCX-gate circuits reference statevectors."""
|
|
targets = []
|
|
# (I^X^I).CCX(0,1,2).(I^X^H) -> |000> + |101>
|
|
targets.append(np.array([1, 0, 0, 0, 0, 1, 0, 0]) / np.sqrt(2))
|
|
# (X^I^I).CCX(2,1,0).(X^H^I) -> |000> + |011>
|
|
targets.append(np.array([1, 0, 0, 1, 0, 0, 0, 0]) / np.sqrt(2))
|
|
return targets
|
|
|
|
|
|
def ccx_gate_unitary_nondeterministic():
|
|
"""CCX-gate circuits reference unitaries."""
|
|
targets = []
|
|
# (I^X^I).CCX(0,1,2).(I^X^H) -> |000> + |101>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[1, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, -1, 0, 0],
|
|
[0, 0, 1, 1, 0, 0, 0, 0],
|
|
[0, 0, 1, -1, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 1, 0, 0],
|
|
[1, -1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 1],
|
|
[0, 0, 0, 0, 0, 0, 1, -1],
|
|
]
|
|
)
|
|
/ np.sqrt(2)
|
|
)
|
|
# (X^I^I).CCX(2,1,0).(X^H^I) -> |000> + |011>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[1, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 1, 0, 0, 0, 0],
|
|
[0, 1, 0, -1, 0, 0, 0, 0],
|
|
[1, 0, -1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 1, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 1],
|
|
[0, 0, 0, 0, 1, 0, -1, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, -1],
|
|
]
|
|
)
|
|
/ np.sqrt(2)
|
|
)
|
|
return targets
|
|
|
|
|
|
# ==========================================================================
|
|
# CSWAP-gate (Fredkin)
|
|
# ==========================================================================
|
|
def cswap_gate_circuits_deterministic(final_measure):
|
|
"""cswap-gate test circuits with deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(3)
|
|
if final_measure:
|
|
cr = ClassicalRegister(3)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# CSWAP(0,1,2) # -> |000>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(X^I^I) -> |100>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(I^X^I) -> |010>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(X^X^I) -> |110>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[1])
|
|
circuit.x(qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(I^I^X) -> |001>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(I^X^X -> |101>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.x(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(X^I^X) -> |011>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.x(qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(X^X^X) -> |111>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.x(qr[1])
|
|
circuit.x(qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(1,0,2).(I^X^X) -> |110>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.x(qr[1])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[1], qr[0], qr[2])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(2,1,0).(X^I^X) -> |110>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.x(qr[2])
|
|
circuit.barrier(qr)
|
|
circuit.cswap(qr[2], qr[1], qr[0])
|
|
circuit.barrier(qr)
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
return circuits
|
|
|
|
|
|
def cswap_gate_counts_deterministic(shots, hex_counts=True):
|
|
""" "cswap-gate circuits reference counts."""
|
|
targets = []
|
|
|
|
if hex_counts:
|
|
# CSWAP(0,1,2) # -> |000>
|
|
targets.append({"0x0": shots})
|
|
# CSWAP(0,1,2).(X^I^I) -> |100>
|
|
targets.append({"0x4": shots})
|
|
# CSWAP(0,1,2).(I^X^I) -> |010>
|
|
targets.append({"0x2": shots})
|
|
# CSWAP(0,1,2).(X^X^I) -> |110>
|
|
targets.append({"0x6": shots})
|
|
# CSWAP(0,1,2).(I^I^X). -> |001>
|
|
targets.append({"0x1": shots})
|
|
# CSWAP(0,1,2).(I^X^X) -> |101>
|
|
targets.append({"0x5": shots})
|
|
# CSWAP(0,1,2).(X^I^X) -> |011>
|
|
targets.append({"0x3": shots})
|
|
# CSWAP(0,1,2).(X^X^X) -> |111>
|
|
targets.append({"0x7": shots})
|
|
# CSWAP(1,0,2).(I^X^X) -> |110>
|
|
targets.append({"0x6": shots})
|
|
# CSWAP(2,1,0).(X^I^X) -> |110>
|
|
targets.append({"0x6": shots})
|
|
else:
|
|
# CSWAP(0,1,2) # -> |000>
|
|
targets.append({"000": shots})
|
|
# CSWAP(0,1,2).(X^I^I) -> |100>
|
|
targets.append({"100": shots})
|
|
# CSWAP(0,1,2).(I^X^I) -> |010>
|
|
targets.append({"010": shots})
|
|
# CSWAP(0,1,2).(X^X^I) -> |110>
|
|
targets.append({"110": shots})
|
|
# CSWAP(0,1,2).(I^I^X) -> |001>
|
|
targets.append({"001": shots})
|
|
# CSWAP(0,1,2).(I^X^X) -> |101>
|
|
targets.append({"101": shots})
|
|
# CSWAP(0,1,2).(X^I^X) -> |011>
|
|
targets.append({"011": shots})
|
|
# CSWAP(0,1,2).(X^X^X) -> |111>
|
|
targets.append({"111": shots})
|
|
# CSWAP(1,0,2).(I^X^X) -> |110>
|
|
targets.append({"110": shots})
|
|
# CSWAP(2,1,0).(X^I^X) -> |110>
|
|
targets.append({"110": shots})
|
|
return targets
|
|
|
|
|
|
def cswap_gate_circuits_nondeterministic(final_measure=True):
|
|
"""cswap-gate test circuits with deterministic counts."""
|
|
circuits = []
|
|
qr = QuantumRegister(3)
|
|
if final_measure:
|
|
cr = ClassicalRegister(3)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# CSWAP(0,1,2).(H^H^H)
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[0])
|
|
circuit.h(qr[1])
|
|
circuit.h(qr[2])
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(X^I^H). -> |100> + |011>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[0])
|
|
circuit.x(qr[2])
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(I^X^H). -> |010> + |101>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[0])
|
|
circuit.x(qr[1])
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(I^H^I) -> |010>+|000>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(H^I^I) -> |100>+|000>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[2])
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
# CSWAP(0,1,2).(I^I^H) -> |001>+|000>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[0])
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CSWAP(0,1,2).(X^X^H) -> |110> + |111>
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[0])
|
|
circuit.x(qr[1])
|
|
circuit.x(qr[2])
|
|
circuit.cswap(qr[0], qr[1], qr[2])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def cswap_gate_counts_nondeterministic(shots, hex_counts=True):
|
|
targets = []
|
|
|
|
if hex_counts:
|
|
# CSWAP(0,1,2).(H^H^H) -> |--->
|
|
targets.append(
|
|
{
|
|
"0x0": shots / 8,
|
|
"0x1": shots / 8,
|
|
"0x2": shots / 8,
|
|
"0x3": shots / 8,
|
|
"0x4": shots / 8,
|
|
"0x5": shots / 8,
|
|
"0x6": shots / 8,
|
|
"0x7": shots / 8,
|
|
}
|
|
)
|
|
# CSWAP(0,1,2).(X^I^H). -> |100> + |011>
|
|
targets.append({"0x3": shots / 2, "0x4": shots / 2})
|
|
# CSWAP(0,1,2).(I^X^H). -> |010> + |101>
|
|
targets.append({"0x2": shots / 2, "0x5": shots / 2})
|
|
# CSWAP(0,1,2).(I^H^I) -> |0-0>
|
|
targets.append({"0x2": shots / 2, "0x0": shots / 2})
|
|
# CSWAP(0,1,2).(H^I^I) -> |-00>
|
|
targets.append({"0x4": shots / 2, "0x0": shots / 2})
|
|
# CSWAP(0,1,2).(I^I^H) -> |00->
|
|
targets.append({"0x0": shots / 2, "0x1": shots / 2})
|
|
# CSWAP(0,1,2).(X^X^H) -> |110> + |111>
|
|
targets.append({"0x6": shots / 2, "0x7": shots / 2})
|
|
|
|
else:
|
|
# CSWAP(0,1,2).(H^H^H) -> |--->
|
|
targets.append(
|
|
{
|
|
"000": shots / 8,
|
|
"001": shots / 8,
|
|
"010": shots / 8,
|
|
"011": shots / 8,
|
|
"100": shots / 8,
|
|
"101": shots / 8,
|
|
"110": shots / 8,
|
|
"111": shots / 8,
|
|
}
|
|
)
|
|
# CSWAP(0,1,2).(X^I^H). -> |100> + |011>
|
|
targets.append({"011": shots / 2, "100": shots / 2})
|
|
# CSWAP(0,1,2).(I^X^H). -> |010> + |101>
|
|
targets.append({"010": shots / 2, "101": shots / 2})
|
|
# CSWAP(0,1,2).(I^H^I) -> |0-0>
|
|
targets.append({"010": shots / 2, "000": shots / 2})
|
|
# CSWAP(0,1,2).(H^I^I) -> |-00>
|
|
targets.append({"100": shots / 2, "000": shots / 2})
|
|
# CSWAP(0,1,2).(I^I^H) -> |00->
|
|
targets.append({"001": shots / 2, "000": shots / 2})
|
|
# CSWAP(0,1,2).(X^X^H) -> |110> + |111>
|
|
targets.append({"110": shots / 2, "111": shots / 2})
|
|
|
|
return targets
|
|
|
|
|
|
def cswap_gate_statevector_deterministic():
|
|
targets = []
|
|
# CSWAP(0,1,2) # -> |000>
|
|
targets.append(np.array([1, 0, 0, 0, 0, 0, 0, 0]))
|
|
# CSWAP(0,1,2).(X^I^I) -> |100>
|
|
targets.append(np.array([0, 0, 0, 0, 1, 0, 0, 0]))
|
|
# CSWAP(0,1,2).(I^X^I) -> |010>
|
|
targets.append(np.array([0, 0, 1, 0, 0, 0, 0, 0]))
|
|
# CSWAP(0,1,2).(X^X^I) -> |110>
|
|
targets.append(np.array([0, 0, 0, 0, 0, 0, 1, 0]))
|
|
# CSWAP(0,1,2).(I^I^X) -> |001>
|
|
targets.append(np.array([0, 1, 0, 0, 0, 0, 0, 0]))
|
|
# CSWAP(0,1,2).(I^X^X) -> |101>
|
|
targets.append(np.array([0, 0, 0, 0, 0, 1, 0, 0]))
|
|
# CSWAP(0,1,2).(X^I^X) -> |011>
|
|
targets.append(np.array([0, 0, 0, 1, 0, 0, 0, 0]))
|
|
# CSWAP(0,1,2).(X^X^X) -> |111>
|
|
targets.append(np.array([0, 0, 0, 0, 0, 0, 0, 1]))
|
|
# CSWAP(1,0,2).(I^X^X) -> |110>
|
|
targets.append(np.array([0, 0, 0, 0, 0, 0, 1, 0]))
|
|
# CSWAP(2,1,0).(X^I^X) -> |110>
|
|
targets.append(np.array([0, 0, 0, 0, 0, 0, 1, 0]))
|
|
return targets
|
|
|
|
|
|
def cswap_gate_statevector_nondeterministic():
|
|
targets = []
|
|
# CSWAP(0,1,2).(H^H^H) -> |--->
|
|
targets.append(np.array([1, 1, 1, 1, 1, 1, 1, 1]) / np.sqrt(8))
|
|
# CSWAP(0,1,2).(X^I^H). -> |100> + |011>
|
|
targets.append(np.array([0, 0, 0, 1, 1, 0, 0, 0]) / np.sqrt(2))
|
|
# CSWAP(0,1,2).(I^X^H). -> |010> + |101>
|
|
targets.append(np.array([0, 0, 1, 0, 0, 1, 0, 0]) / np.sqrt(2))
|
|
# CSWAP(0,1,2).(I^H^I) -> |0-0>
|
|
targets.append(np.array([1, 0, 1, 0, 0, 0, 0, 0]) / np.sqrt(2))
|
|
# CSWAP(0,1,2).(H^I^I) -> |-00>
|
|
targets.append(np.array([1, 0, 0, 0, 1, 0, 0, 0]) / np.sqrt(2))
|
|
# CSWAP(0,1,2).(I^I^H) -> |00->
|
|
targets.append(np.array([1, 1, 0, 0, 0, 0, 0, 0]) / np.sqrt(2))
|
|
# CSWAP(0,1,2).(X^X^H) -> |110> + |111>
|
|
targets.append(np.array([0, 0, 0, 0, 0, 0, 1, 1]) / np.sqrt(2))
|
|
return targets
|
|
|
|
|
|
def cswap_gate_unitary_deterministic():
|
|
"""cswap-gate circuits reference unitaries."""
|
|
targets = []
|
|
|
|
# CSWAP(0,1,2) # -> |000>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(0,1,2).(X^I^I) -> |100>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(0,1,2).(I^X^I) -> |010>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(0,1,2).(X^X^I) -> |110>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(0,1,2).(I^I^X) -> |001>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(0,1,2).(I^X^X) -> |101>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(0,1,2).(X^I^X) -> |011>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(0,1,2).(X^X^X) -> |111>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(1,0,2).(I^X^X) -> |110>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
# CSWAP(2,1,0).(X^I^X) -> |110>
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 0, 1, 0, 0],
|
|
[0, 0, 0, 0, 1, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1],
|
|
[0, 0, 0, 0, 0, 0, 1, 0],
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 1, 0, 0, 0, 0],
|
|
[1, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 1, 0, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
return targets
|
|
|
|
|
|
def cswap_gate_unitary_nondeterministic():
|
|
"""cswap-gate circuits reference unitaries."""
|
|
targets = []
|
|
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
],
|
|
[
|
|
0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
],
|
|
[
|
|
0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
],
|
|
[
|
|
0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
],
|
|
[
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
],
|
|
[
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
],
|
|
[
|
|
0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
],
|
|
[
|
|
0.35355339,
|
|
-0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
0.35355339,
|
|
0.35355339,
|
|
-0.35355339,
|
|
],
|
|
]
|
|
)
|
|
)
|
|
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 0.70710678, 0.70710678, 0, 0],
|
|
[0, 0, 0, 0, 0.70710678, -0.70710678, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, 0.70710678],
|
|
[0.70710678, -0.70710678, 0, 0, 0, 0, 0, 0],
|
|
[0.70710678, 0.70710678, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, -0.70710678],
|
|
[0, 0, 0.70710678, 0.70710678, 0, 0, 0, 0],
|
|
[0, 0, 0.70710678, -0.70710678, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0.70710678, 0.70710678, 0, 0, 0, 0],
|
|
[0, 0, 0.70710678, -0.70710678, 0, 0, 0, 0],
|
|
[0.70710678, 0.70710678, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, -0.70710678],
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, 0.70710678],
|
|
[0.70710678, -0.70710678, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0.70710678, 0.70710678, 0, 0],
|
|
[0, 0, 0, 0, 0.70710678, -0.70710678, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0.70710678, 0, 0.70710678, 0, 0, 0, 0, 0],
|
|
[0, 0.70710678, 0, 0.70710678, 0, 0, 0, 0],
|
|
[0.70710678, 0, -0.70710678, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0.70710678, 0, 0.70710678],
|
|
[0, 0, 0, 0, 0.70710678, 0, 0.70710678, 0],
|
|
[0, 0.70710678, 0, -0.70710678, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0.70710678, 0, -0.70710678, 0],
|
|
[0, 0, 0, 0, 0, 0.70710678, 0, -0.70710678],
|
|
]
|
|
)
|
|
)
|
|
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0.70710678, 0, 0, 0, 0.70710678, 0, 0, 0],
|
|
[0, 0.70710678, 0, 0, 0, 0.70710678, 0, 0],
|
|
[0, 0, 0.70710678, 0, 0, 0, 0.70710678, 0],
|
|
[0, 0.70710678, 0, 0, 0, -0.70710678, 0, 0],
|
|
[0.70710678, 0, 0, 0, -0.70710678, 0, 0, 0],
|
|
[0, 0, 0, 0.70710678, 0, 0, 0, 0.70710678],
|
|
[0, 0, 0.70710678, 0, 0, 0, -0.70710678, 0],
|
|
[0, 0, 0, 0.70710678, 0, 0, 0, -0.70710678],
|
|
]
|
|
)
|
|
)
|
|
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0.70710678, 0.70710678, 0, 0, 0, 0, 0, 0],
|
|
[0.70710678, -0.70710678, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0.70710678, 0.70710678, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0.70710678, -0.70710678, 0, 0],
|
|
[0, 0, 0, 0, 0.70710678, 0.70710678, 0, 0],
|
|
[0, 0, 0.70710678, -0.70710678, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, 0.70710678],
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, -0.70710678],
|
|
]
|
|
)
|
|
)
|
|
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, 0.70710678],
|
|
[0, 0, 0, 0, 0, 0, 0.70710678, -0.70710678],
|
|
[0, 0, 0, 0, 0.70710678, 0.70710678, 0, 0],
|
|
[0, 0, 0.70710678, -0.70710678, 0, 0, 0, 0],
|
|
[0, 0, 0.70710678, 0.70710678, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0.70710678, -0.70710678, 0, 0],
|
|
[0.70710678, 0.70710678, 0, 0, 0, 0, 0, 0],
|
|
[0.70710678, -0.70710678, 0, 0, 0, 0, 0, 0],
|
|
]
|
|
)
|
|
)
|
|
return targets
|
|
|
|
|
|
# ==========================================================================
|
|
# CU1
|
|
# ==========================================================================
|
|
def cu1_gate_circuits_nondeterministic(final_measure):
|
|
circuits = []
|
|
qr = QuantumRegister(2)
|
|
if final_measure:
|
|
cr = ClassicalRegister(2)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# H^X.CU1(0,0,1).H^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.cp(0, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.h(qr[1])
|
|
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^I.CU1(pi,0,1).H^I
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.cp(np.pi, qr[0], qr[1])
|
|
circuit.h(qr[1])
|
|
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^X.CU1(pi/4,0,1).H^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.cp(np.pi / 4, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.h(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^X.CU1(pi/2,0,1).H^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.cp(np.pi / 2, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.h(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^X.CU1(pi,0,1).H^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.cp(np.pi, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.h(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^H.CU1(0,0,1).H^H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.h(qr[0])
|
|
circuit.cp(0, qr[0], qr[1])
|
|
circuit.h(qr[0])
|
|
circuit.h(qr[1])
|
|
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^H.CU1(pi/2,0,1).H^H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.h(qr[0])
|
|
circuit.cp(np.pi / 2, qr[0], qr[1])
|
|
circuit.h(qr[0])
|
|
circuit.h(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^H.CU1(pi,0,1).H^H
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.h(qr[1])
|
|
circuit.h(qr[0])
|
|
circuit.cp(np.pi, qr[0], qr[1])
|
|
circuit.h(qr[0])
|
|
circuit.h(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def cu1_gate_counts_nondeterministic(shots, hex_counts=True):
|
|
"""CU1-gate circuits reference counts."""
|
|
targets = []
|
|
if hex_counts:
|
|
# H^X.CU1(0,0,1).H^X
|
|
targets.append({"0x0": shots})
|
|
# H^I.CU1(pi,0,1).H^I
|
|
targets.append({"0x0": shots})
|
|
# H^X.CU1(pi/4,0,1).H^X
|
|
targets.append(
|
|
{"0x0": shots * (0.25 * (2 + np.sqrt(2))), "0x2": shots * (0.25 * (2 - np.sqrt(2)))}
|
|
)
|
|
# H^X.CU1(pi/2,0,1).H^X
|
|
targets.append({"0x0": shots * 0.5, "0x2": shots * 0.5})
|
|
# H^X.CU1(pi,0,1).H^X
|
|
targets.append({"0x2": shots})
|
|
# H^H.CU1(0,0,1).H^H
|
|
targets.append({"0x0": shots})
|
|
# H^H.CU1(pi/2,0,1).H^H
|
|
targets.append(
|
|
{"0x0": shots * 0.625, "0x1": shots * 0.125, "0x2": shots * 0.125, "0x3": shots * 0.125}
|
|
)
|
|
# H^H.CU1(pi,0,1).H^H
|
|
targets.append(
|
|
{"0x0": shots * 0.25, "0x1": shots * 0.25, "0x2": shots * 0.25, "0x3": shots * 0.25}
|
|
)
|
|
else:
|
|
# H^X.CU1(0,0,1).H^X
|
|
targets.append({"00": shots})
|
|
# H^I.CU1(pi,0,1).H^I
|
|
targets.append({"00": shots})
|
|
# H^X.CU1(pi/4,0,1).H^X
|
|
targets.append({"00": shots * 0.85, "10": shots * 0.15})
|
|
# H^X.CU1(pi/2,0,1).H^X
|
|
targets.append({"00": shots * 0.5, "10": shots * 0.5})
|
|
# H^X.CU1(pi,0,1).H^X
|
|
targets.append({"10": shots})
|
|
# H^H.CU1(0,0,1).H^H
|
|
targets.append({"00": shots})
|
|
# H^H.CU1(pi/2,0,1).H^H
|
|
targets.append(
|
|
{"00": shots * 0.5125, "01": shots * 0.125, "10": shots * 0.125, "11": shots * 0.125}
|
|
)
|
|
# H^H.CU1(pi,0,1).H^H
|
|
targets.append(
|
|
{"00": shots * 0.25, "01": shots * 0.25, "10": shots * 0.25, "11": shots * 0.25}
|
|
)
|
|
return targets
|
|
|
|
|
|
def cu1_gate_statevector_nondeterministic():
|
|
targets = []
|
|
# H^X.CU1(0,0,1).H^X
|
|
targets.append(np.array([1, 0, 0, 0]))
|
|
# H^I.CU1(pi,0,1).H^I
|
|
targets.append(np.array([1, 0, 0, 0]))
|
|
# H^X.CU1(pi/4,0,1).H^X
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
(0.25 * (2 + np.sqrt(2))) + (1 / (2 * np.sqrt(2))) * 1j,
|
|
0,
|
|
(0.25 * (2 - np.sqrt(2))) - (1 / (2 * np.sqrt(2))) * 1j,
|
|
0,
|
|
]
|
|
)
|
|
)
|
|
# H^X.CU1(pi/2,0,1).H^X
|
|
targets.append(np.array([0.5 + 0.5j, 0, 0.5 - 0.5j, 0]))
|
|
# H^X.CU1(pi,0,1).H^X
|
|
targets.append(np.array([0, 0, 1, 0]))
|
|
# H^H.CU1(0,0,1).H^H
|
|
targets.append(np.array([1, 0, 0, 0]))
|
|
# H^H.CU1(pi/2,0,1).H^H
|
|
targets.append(np.array([0.75 + 0.25j, 0.25 - 0.25j, 0.25 - 0.25j, -0.25 + 0.25j]))
|
|
# H^H.CU1(pi,0,1).H^H
|
|
targets.append(np.array([0.5, 0.5, 0.5, -0.5]))
|
|
return targets
|
|
|
|
|
|
def cu1_gate_unitary_nondeterministic():
|
|
targets = []
|
|
# H^X.CU1(0,0,1).H^X
|
|
targets.append(np.eye(4))
|
|
# H^I.CU1(pi,0,1).H^I
|
|
targets.append(np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0]]))
|
|
# H^X.CU1(pi/4,0,1).H^X
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[
|
|
(0.25 * (2 + np.sqrt(2))) + (1 / (2 * np.sqrt(2))) * 1j,
|
|
0,
|
|
(0.25 * (2 - np.sqrt(2))) - (1 / (2 * np.sqrt(2))) * 1j,
|
|
0,
|
|
],
|
|
[0, 1, 0, 0],
|
|
[
|
|
(0.25 * (2 - np.sqrt(2))) - (1 / (2 * np.sqrt(2))) * 1j,
|
|
0,
|
|
(0.25 * (2 + np.sqrt(2))) + (1 / (2 * np.sqrt(2))) * 1j,
|
|
0,
|
|
],
|
|
[0, 0, 0, 1],
|
|
]
|
|
)
|
|
)
|
|
# H^X.CU1(pi/2,0,1).H^X
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[0.5 + 0.5j, 0, 0.5 - 0.5j, 0],
|
|
[0, 1, 0, 0],
|
|
[0.5 - 0.5j, 0, 0.5 + 0.5j, 0],
|
|
[0, 0, 0, 1],
|
|
]
|
|
)
|
|
)
|
|
# H^X.CU1(pi,0,1).H^X
|
|
targets.append(np.array([[0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1]]))
|
|
# H^H.CU1(0,0,1).H^H
|
|
targets.append(np.eye(4))
|
|
# H^H.CU1(pi/2,0,1).H^H
|
|
targets.append(
|
|
(0.75 + 0.25j) * np.eye(4)
|
|
+ (0.25 - 0.25j) * np.array([[0, 1, 1, -1], [1, 0, -1, 1], [1, -1, 0, 1], [-1, 1, 1, 0]])
|
|
)
|
|
# H^H.CU1(pi,0,1).H^H
|
|
targets.append(0.5 * np.array([[1, 1, 1, -1], [1, 1, -1, 1], [1, -1, 1, 1], [-1, 1, 1, 1]]))
|
|
return targets
|
|
|
|
|
|
# ==========================================================================
|
|
# CU3
|
|
# ==========================================================================
|
|
def cu3_gate_circuits_deterministic(final_measure):
|
|
circuits = []
|
|
qr = QuantumRegister(2)
|
|
if final_measure:
|
|
cr = ClassicalRegister(2)
|
|
regs = (qr, cr)
|
|
else:
|
|
regs = (qr,)
|
|
|
|
# I^X.CI.I^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.cu(0, 0, 0, 0, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# CX
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.cu(np.pi, 0, np.pi, 0, qr[0], qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# I^X.CX.I^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.cu(np.pi, 0, np.pi, 0, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# H^X.CH.I^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.cu(np.pi / 2, 0, np.pi, 0, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
circuit.h(qr[1])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# I^X.CRX(pi).I^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.cu(np.pi, -np.pi / 2, np.pi / 2, 0, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
# I^X.CRY(pi).I^X
|
|
circuit = QuantumCircuit(*regs)
|
|
circuit.x(qr[0])
|
|
circuit.cu(np.pi, 0, 0, 0, qr[0], qr[1])
|
|
circuit.x(qr[0])
|
|
if final_measure:
|
|
circuit.barrier(qr)
|
|
circuit.measure(qr, cr)
|
|
circuits.append(circuit)
|
|
|
|
return circuits
|
|
|
|
|
|
def cu3_gate_unitary_deterministic():
|
|
targets = []
|
|
|
|
# I^X.CI.I^X
|
|
targets.append(np.eye(4))
|
|
|
|
# CX
|
|
targets.append(np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0]]))
|
|
|
|
# I^X.CX.I^X
|
|
targets.append(np.array([[0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1]]))
|
|
|
|
# H^X.CH.I^X
|
|
targets.append(
|
|
np.array(
|
|
[
|
|
[1, 0, 0, 0],
|
|
[0, 1 / np.sqrt(2), 0, 1 / np.sqrt(2)],
|
|
[0, 0, 1, 0],
|
|
[0, 1 / np.sqrt(2), 0, -1 / np.sqrt(2)],
|
|
]
|
|
)
|
|
)
|
|
|
|
# I^X.CRX(pi).I^X
|
|
targets.append(np.array([[0, 0, -1j, 0], [0, 1, 0, 0], [-1j, 0, 0, 0], [0, 0, 0, 1]]))
|
|
|
|
# I^X.CRY(pi).I^X
|
|
targets.append(np.array([[0, 0, -1, 0], [0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1]]))
|
|
|
|
return targets
|
|
|
|
|
|
def cu3_gate_statevector_deterministic():
|
|
init_state = np.array([1, 0, 0, 0])
|
|
targets = [mat.dot(init_state) for mat in cu3_gate_unitary_deterministic()]
|
|
|
|
return targets
|
|
|
|
|
|
def cu3_gate_counts_deterministic(shots, hex_counts=True):
|
|
"""CU2-gate circuits reference counts."""
|
|
probs = [np.abs(vec) ** 2 for vec in cu3_gate_statevector_deterministic()]
|
|
targets = []
|
|
for prob in probs:
|
|
if hex_counts:
|
|
targets.append({hex(i): shots * p for i, p in enumerate(prob)})
|
|
else:
|
|
counts = {}
|
|
for i, p in enumerate(prob):
|
|
key = bin(i)[2:]
|
|
key = (2 - len(key)) * "0" + key
|
|
counts[key] = shots * p
|
|
targets.append(counts)
|
|
return targets
|