Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine results, apply controlled gates and measure to whole registers #23

Merged
merged 4 commits into from
Aug 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions qiskit/_quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def add(self, *regs):
self.regs[register.name] = register
else:
raise QISKitError("register name \"%s\" already exists"
% register.name)
% register.name)

def _check_qreg(self, register):
"""Raise exception if r is not in this circuit or not qreg."""
Expand Down Expand Up @@ -174,10 +174,17 @@ def qasm(self):

def measure(self, qubit, cbit):
"""Measure quantum bit into classical bit (tuples)."""
self._check_qubit(qubit)
self._check_creg(cbit[0])
cbit[0].check_range(cbit[1])
return self._attach(Measure(qubit, cbit, self))
if isinstance(qubit, QuantumRegister) and \
isinstance(cbit, ClassicalRegister) and len(qubit) == len(cbit):
instructions = InstructionSet()
for i in range(qubit.size):
instructions.add(self.measure((qubit, i), (cbit, i)))
return instructions
else:
self._check_qubit(qubit)
self._check_creg(cbit[0])
cbit[0].check_range(cbit[1])
return self._attach(Measure(qubit, cbit, self))

def reset(self, quantum_register):
"""Reset q."""
Expand Down
34 changes: 34 additions & 0 deletions qiskit/_quantumprogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import os
import string
import re
import copy

# use the external IBMQuantumExperience Library
from IBMQuantumExperience.IBMQuantumExperience import IBMQuantumExperience
Expand Down Expand Up @@ -1182,6 +1183,39 @@ def __str__(self):
"""
return self.__result['status']

def __iadd__(self, other):
"""Append a Result object to current Result object.

Arg:
other (Result): a Result object to append.
Returns:
The current object with appended results.
"""
if self.__qobj['config'] == other.__qobj['config']:
if isinstance(self.__qobj['id'], str):
self.__qobj['id'] = [self.__qobj['id']]
self.__qobj['id'].append(other.__qobj['id'])
self.__qobj['circuits'] += other.__qobj['circuits']
self.__result['result'] += other.__result['result']
return self
else:
raise QISKitError('Result objects have different configs and cannot be combined.')

def __add__(self, other):
"""Combine Result objects.

Note that the qobj id of the returned result will be the same as the
first result.

Arg:
other (Result): a Result object to combine.
Returns:
A new Result object consisting of combined objects.
"""
ret = copy.deepcopy(self)
ret += other
return ret

def get_error(self):
if self.__result['status'] == 'ERROR':
return self.__result['result'][0]
Expand Down
19 changes: 14 additions & 5 deletions qiskit/extensions/standard/ch.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header

from qiskit._quantumregister import QuantumRegister
from qiskit._instructionset import InstructionSet

class CHGate(Gate):
"""controlled-H gate."""
Expand All @@ -49,10 +50,18 @@ def reapply(self, circ):

def ch(self, ctl, tgt):
"""Apply CH from ctl to tgt."""
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CHGate(ctl, tgt, self))
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.ch((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CHGate(ctl, tgt, self))


QuantumCircuit.ch = ch
Expand Down
19 changes: 14 additions & 5 deletions qiskit/extensions/standard/crz.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header

from qiskit._quantumregister import QuantumRegister
from qiskit._instructionset import InstructionSet

class CrzGate(Gate):
"""controlled-rz gate."""
Expand Down Expand Up @@ -51,10 +52,18 @@ def reapply(self, circ):

def crz(self, theta, ctl, tgt):
"""Apply crz from ctl to tgt with angle theta."""
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CrzGate(theta, ctl, tgt, self))
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.crz(theta, (ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CrzGate(theta, ctl, tgt, self))


QuantumCircuit.crz = crz
Expand Down
18 changes: 14 additions & 4 deletions qiskit/extensions/standard/cu1.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit._instructionset import InstructionSet


class Cu1Gate(Gate):
Expand Down Expand Up @@ -51,10 +53,18 @@ def reapply(self, circ):

def cu1(self, theta, ctl, tgt):
"""Apply cu1 from ctl to tgt with angle theta."""
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu1Gate(theta, ctl, tgt, self))
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.cu1(theta, (ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu1Gate(theta, ctl, tgt, self))


QuantumCircuit.cu1 = cu1
Expand Down
18 changes: 14 additions & 4 deletions qiskit/extensions/standard/cu3.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit._instructionset import InstructionSet


class Cu3Gate(Gate):
Expand Down Expand Up @@ -57,10 +59,18 @@ def reapply(self, circ):

def cu3(self, theta, phi, lam, ctl, tgt):
"""Apply cu3 from ctl to tgt with angle theta, phi, lam."""
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu3Gate(theta, phi, lam, ctl, tgt, self))
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.cu3(theta, phi, lam, (ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu3Gate(theta, phi, lam, ctl, tgt, self))


QuantumCircuit.cu3 = cu3
Expand Down
18 changes: 14 additions & 4 deletions qiskit/extensions/standard/cx.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit._instructionset import InstructionSet


class CnotGate(Gate):
Expand Down Expand Up @@ -49,10 +51,18 @@ def reapply(self, circ):

def cx(self, ctl, tgt):
"""Apply CNOT from ctl to tgt."""
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CnotGate(ctl, tgt, self))
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((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CnotGate(ctl, tgt, self))


QuantumCircuit.cx = cx
Expand Down
19 changes: 14 additions & 5 deletions qiskit/extensions/standard/cy.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header

from qiskit._quantumregister import QuantumRegister
from qiskit._instructionset import InstructionSet

class CyGate(Gate):
"""controlled-Y gate."""
Expand All @@ -49,10 +50,18 @@ def reapply(self, circ):

def cy(self, ctl, tgt):
"""Apply CY to circuit."""
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CyGate(ctl, tgt, self))
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.cy((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CyGate(ctl, tgt, self))


QuantumCircuit.cy = cy
Expand Down
19 changes: 14 additions & 5 deletions qiskit/extensions/standard/cz.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header

from qiskit._quantumregister import QuantumRegister
from qiskit._instructionset import InstructionSet

class CzGate(Gate):
"""controlled-Z gate."""
Expand All @@ -48,10 +49,18 @@ def reapply(self, circ):

def cz(self, ctl, tgt):
"""Apply CZ to circuit."""
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CzGate(ctl, tgt, self))
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.cz((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CzGate(ctl, tgt, self))


QuantumCircuit.cz = cz
Expand Down
31 changes: 25 additions & 6 deletions test/python/test_quantumprogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,12 +802,8 @@ def test_run_program(self):
qc2.cx(qr[0], qr[1])
qc2.cx(qr[0], qr[2])
qc3.h(qr)
qc2.measure(qr[0], cr[0])
qc3.measure(qr[0], cr[0])
qc2.measure(qr[1], cr[1])
qc3.measure(qr[1], cr[1])
qc2.measure(qr[2], cr[2])
qc3.measure(qr[2], cr[2])
qc2.measure(qr, cr)
qc3.measure(qr, cr)
circuits = ['qc2', 'qc3']
shots = 1024 # the number of shots in the experiment.
backend = 'local_qasm_simulator'
Expand All @@ -821,6 +817,29 @@ def test_run_program(self):
'100': 117, '000': 129, '101': 126,
'010': 145, '011': 125})

def test_combine_results(self):
"""Test run.

If all correct should the data.
"""
QP_program = QuantumProgram()
qr = QP_program.create_quantum_register("qr", 1)
cr = QP_program.create_classical_register("cr", 1)
qc1 = QP_program.create_circuit("qc1", [qr], [cr])
qc2 = QP_program.create_circuit("qc2", [qr], [cr])
qc1.measure(qr[0], cr[0])
qc2.x(qr[0])
qc2.measure(qr[0], cr[0])
shots = 1024 # the number of shots in the experiment.
backend = 'local_qasm_simulator'
res1 = QP_program.execute(['qc1'], backend=backend, shots=shots)
res2 = QP_program.execute(['qc2'], backend=backend, shots=shots)
counts1 = res1.get_counts('qc1')
counts2 = res2.get_counts('qc2')
res1 += res2 # combine results
counts12 = [res1.get_counts('qc1'), res1.get_counts('qc2')]
self.assertEqual(counts12, [counts1, counts2])

def test_local_qasm_simulator(self):
"""Test execute.

Expand Down