Support for QuantumRegister in gates supporing qubits (#369)

* no name in the registers means no name :-/

* slip assertResult

* simpler

* 352 fix, test_rz_reg and test_s_reg

* test_sdg_reg

* swap behaves as CX when called with registers as args.

* test_swap_reg_reg_inv

* useless =

* cx

* cx_base

* test_rz_reg_inv

* ry and rx

* test_s_reg_inv

* cy and cz

* barrier

* keeping previous behaivor

* ch

* cu3

* cu1

* crz

* crz and h

* iden

* sdg

* t

* tdg

* u1

* u2

* u3

* ubase

* x

* y

* z

* code organization

* barrier for a list of qbits (and formating)

* adding backwards compatibility to barrier

* format

* ccx and cswap

* format

* this extension of instructionset is not needed

* format

* ordered get_{c,q}regs

* invalid tests

* -from qiskit import InstructionSet

* clarification in barrier usage

* do not allow, swap q,r[1]

* qasm stmt should be in new lines

* docstring
This commit is contained in:
Luciano 2018-05-03 13:52:21 -04:00 committed by Diego M. Rodríguez
parent 07b2485cb0
commit 06482631be
14 changed files with 1076 additions and 155 deletions

View File

@ -94,7 +94,7 @@ class QuantumCircuit(object):
def get_qregs(self):
"""Get the qregs from the registers."""
qregs = {}
qregs = OrderedDict()
for name, register in self.regs.items():
if isinstance(register, QuantumRegister):
qregs[name] = register
@ -102,7 +102,7 @@ class QuantumCircuit(object):
def get_cregs(self):
"""Get the cregs from the registers."""
cregs = {}
cregs = OrderedDict()
for name, register in self.regs.items():
if isinstance(register, ClassicalRegister):
cregs[name] = register
@ -202,6 +202,14 @@ class QuantumCircuit(object):
def _check_qubit(self, qubit):
"""Raise exception if qubit is not in this circuit or bad format."""
if not isinstance(qubit, tuple):
raise QISKitError("%s is not a tuple."
"A qubit should be formated as a tuple." % str(qubit))
if not len(qubit) == 2:
raise QISKitError("%s is not a tuple with two elements, but %i instead" % len(qubit))
if not isinstance(qubit[1], int):
raise QISKitError("The second element of a tuple defining a qubit should be an int:"
"%s was found instead" % type(qubit[1]).__name__)
self._check_qreg(qubit[0])
qubit[0].check_range(qubit[1])

View File

@ -22,7 +22,6 @@ from qiskit import Instruction
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import QuantumRegister
from qiskit.extensions._extensionerror import ExtensionError
from qiskit.extensions.standard import header # pylint: disable=unused-import
@ -55,26 +54,28 @@ class Barrier(Instruction):
self._modifiers(circ.barrier(*self.arg))
def barrier(self, *tuples):
"""Apply barrier to tuples (reg, idx)."""
tuples = list(tuples)
if not tuples: # TODO: implement this for all single qubit gates
if isinstance(self, QuantumCircuit):
for register in self.regs.values():
if isinstance(register, QuantumRegister):
tuples.append(register)
if not tuples:
raise ExtensionError("no arguments passed")
def barrier(self, *args):
"""Apply barrier to circuit.
If args is None, applies to all the qbits.
Args is a list of QuantumRegister or single qubits.
For QuantumRegister, applies barrier to all the qbits in that register."""
qubits = []
for tuple_element in tuples:
if isinstance(tuple_element, QuantumRegister):
for j in range(tuple_element.size):
self._check_qubit((tuple_element, j))
qubits.append((tuple_element, j))
if not args: # None
for qreg in self.get_qregs().values():
for j in range(qreg.size):
qubits.append((qreg, j))
for arg in args:
if isinstance(arg, QuantumRegister):
for j in range(arg.size):
qubits.append((arg, j))
else:
self._check_qubit(tuple_element)
qubits.append(tuple_element)
qubits.append(arg)
self._check_dups(qubits)
for qubit in qubits:
self._check_qubit(qubit)
return self._attach(Barrier(qubits, self))

View File

@ -59,6 +59,18 @@ def ch(self, ctl, tgt):
instructions.add(self.ch((ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
gs = InstructionSet()
for j in range(ctl.size):
gs.add(self.ch((ctl, j), tgt))
return gs
if isinstance(tgt, QuantumRegister):
gs = InstructionSet()
for j in range(tgt.size):
gs.add(self.ch(ctl, (tgt, j)))
return gs
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -60,6 +60,18 @@ def crz(self, theta, ctl, tgt):
instructions.add(self.crz(theta, (ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
instructions = InstructionSet()
for j in range(ctl.size):
instructions.add(self.crz(theta, (ctl, j), tgt))
return instructions
if isinstance(tgt, QuantumRegister):
instructions = InstructionSet()
for j in range(tgt.size):
instructions.add(self.crz(theta, ctl, (tgt, j)))
return instructions
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -60,6 +60,18 @@ def cu1(self, theta, ctl, tgt):
instructions.add(self.cu1(theta, (ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
instructions = InstructionSet()
for j in range(ctl.size):
instructions.add(self.cu1(theta, (ctl, j), tgt))
return instructions
if isinstance(tgt, QuantumRegister):
instructions = InstructionSet()
for j in range(tgt.size):
instructions.add(self.cu1(theta, ctl, (tgt, j)))
return instructions
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -67,6 +67,18 @@ def cu3(self, theta, phi, lam, ctl, tgt):
instructions.add(self.cu3(theta, phi, lam, (ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
instructions = InstructionSet()
for j in range(ctl.size):
instructions.add(self.cu3(theta, phi, lam, (ctl, j), tgt))
return instructions
if isinstance(tgt, QuantumRegister):
instructions = InstructionSet()
for j in range(tgt.size):
instructions.add(self.cu3(theta, phi, lam, ctl, (tgt, j)))
return instructions
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -51,7 +51,7 @@ class CnotGate(Gate):
def cx(self, ctl, tgt):
"""Apply CNOT from ctl to tgt."""
"""Apply CX from ctl to tgt."""
if isinstance(ctl, QuantumRegister) and \
isinstance(tgt, QuantumRegister) and len(ctl) == len(tgt):
instructions = InstructionSet()
@ -59,6 +59,18 @@ def cx(self, ctl, tgt):
instructions.add(self.cx((ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
gs = InstructionSet()
for j in range(ctl.size):
gs.add(self.cx((ctl, j), tgt))
return gs
if isinstance(tgt, QuantumRegister):
gs = InstructionSet()
for j in range(tgt.size):
gs.add(self.cx(ctl, (tgt, j)))
return gs
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -21,6 +21,8 @@ Fundamental controlled-NOT gate.
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
@ -49,6 +51,27 @@ class CXBase(Gate):
def cx_base(self, ctl, tgt):
"""Apply CX ctl, tgt."""
if isinstance(ctl, QuantumRegister) and \
isinstance(tgt, QuantumRegister) and len(ctl) == len(tgt):
# apply CX to qubits between two registers
instructions = InstructionSet()
for i in range(ctl.size):
instructions.add(self.cx_base((ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
instructions = InstructionSet()
for j in range(ctl.size):
instructions.add(self.cx_base((ctl, j), tgt))
return instructions
if isinstance(tgt, QuantumRegister):
instructions = InstructionSet()
for j in range(tgt.size):
instructions.add(self.cx_base(ctl, (tgt, j)))
return instructions
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -59,6 +59,18 @@ def cy(self, ctl, tgt):
instructions.add(self.cy((ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
gs = InstructionSet()
for j in range(ctl.size):
gs.add(self.cy((ctl, j), tgt))
return gs
if isinstance(tgt, QuantumRegister):
gs = InstructionSet()
for j in range(tgt.size):
gs.add(self.cy(ctl, (tgt, j)))
return gs
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -58,6 +58,18 @@ def cz(self, ctl, tgt):
instructions.add(self.cz((ctl, i), (tgt, i)))
return instructions
if isinstance(ctl, QuantumRegister):
instructions = InstructionSet()
for j in range(ctl.size):
instructions.add(self.cz((ctl, j), tgt))
return instructions
if isinstance(tgt, QuantumRegister):
instructions = InstructionSet()
for j in range(tgt.size):
instructions.add(self.cz(ctl, (tgt, j)))
return instructions
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])

View File

@ -56,6 +56,12 @@ def h(self, q):
instructions.add(self.h((q, j)))
return instructions
if isinstance(q, QuantumRegister):
instructions = InstructionSet()
for j in range(q.size):
instructions.add(self.h(q))
return instructions
self._check_qubit(q)
return self._attach(HGate(q, self))

View File

@ -53,10 +53,10 @@ class SwapGate(Gate):
def swap(self, ctl, tgt):
"""Apply SWAP from ctl to tgt."""
if isinstance(ctl, QuantumRegister) and \
isinstance(tgt, QuantumRegister) and len(ctl) == len(tgt):
isinstance(tgt, QuantumRegister) and len(ctl) == len(tgt):
instructions = InstructionSet()
for i in range(ctl.size):
instructions.add(self.swap((ctl, i), (tgt, i)))
for j in range(ctl.size):
instructions.add(self.swap((ctl, j), (tgt, j)))
return instructions
self._check_qubit(ctl)

View File

@ -21,7 +21,9 @@ Element of SU(2).
"""
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
@ -59,6 +61,12 @@ class UBase(Gate):
def u_base(self, theta, phi, lam, q):
"""Apply U to q."""
if isinstance(q, QuantumRegister):
gs = InstructionSet()
for j in range(q.size):
gs.add(self.u_base(theta, phi, lam, (q, j)))
return gs
self._check_qubit(q)
return self._attach(UBase(theta, phi, lam, q, self))

File diff suppressed because it is too large Load Diff