Skip to content

Commit

Permalink
Merge branch 'master' into 4757
Browse files Browse the repository at this point in the history
  • Loading branch information
mtreinish authored Aug 4, 2020
2 parents 853cf40 + 83d40dd commit e0a9f73
Show file tree
Hide file tree
Showing 180 changed files with 3,708 additions and 970 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ is that if your code contribution has user facing changes that you will write
the release documentation for these changes. This documentation must explain
what was changed, why it was changed, and how users can either use or adapt
to the change. The idea behind release documentation is that when a naive
user with limited internal knowledege of the project is upgrading from the
user with limited internal knowledge of the project is upgrading from the
previous release to the new one, they should be able to read the release notes,
understand if they need to update their program which uses qiskit, and how they
would go about doing that. It ideally should explain why they need to make
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ If you'd like to contribute to Qiskit Terra, please take a look at our
[contribution guidelines](CONTRIBUTING.md). This project adheres to Qiskit's [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.

We use [GitHub issues](https://github.com/Qiskit/qiskit-terra/issues) for tracking requests and bugs. Please
[join the Qiskit Slack community](https://join.slack.com/t/qiskit/shared_invite/zt-e4sscbg2-p8NHTezPVkC3r8nV6BIUVw)
[join the Qiskit Slack community](https://ibm.co/joinqiskitslack)
and use our [Qiskit Slack channel](https://qiskit.slack.com) for discussion and simple questions.
For questions that are more suited for a forum we use the Qiskit tag in the [Stack Exchange](https://quantumcomputing.stackexchange.com/questions/tagged/qiskit).

Expand All @@ -119,7 +119,7 @@ https://github.com/Qiskit/qiskit-terra/releases/tag/0.9.0

The changelog for the current release can be found in the releases tab:
![](https://img.shields.io/github/release/Qiskit/qiskit-terra.svg?style=popout-square)
The changelog provides a quick overview of noteable changes for a given
The changelog provides a quick overview of noteble changes for a given
release.

Additionally, as part of each release detailed release notes are written to
Expand Down
3 changes: 2 additions & 1 deletion postBuild
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

# Dependencies
# - matplotlib: for MPL drawer
# - pylatexenc: for MPL drawer
# - pillow: for image comparison
# - appmode: jupyter extension for executing the notebook
pip install matplotlib pillow appmode
pip install matplotlib pylatexenc pillow appmode

# Activation of appmode extension
jupyter nbextension enable --py --sys-prefix appmode
Expand Down
3 changes: 2 additions & 1 deletion qiskit/assembler/assemble_circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def _assemble_circuit(circuit):
clbit_labels=clbit_labels,
memory_slots=memory_slots,
creg_sizes=creg_sizes,
name=circuit.name)
name=circuit.name,
global_phase=circuit.global_phase)
# TODO: why do we need n_qubits and memory_slots in both the header and the config
config = QasmQobjExperimentConfig(n_qubits=num_qubits, memory_slots=memory_slots)

Expand Down
104 changes: 61 additions & 43 deletions qiskit/circuit/add_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,57 +99,75 @@ def control(operation: Union[Gate, ControlledGate],
from math import pi
# pylint: disable=cyclic-import
import qiskit.circuit.controlledgate as controlledgate
# pylint: disable=unused-import
import qiskit.circuit.library.standard_gates.multi_control_rotation_gates

q_control = QuantumRegister(num_ctrl_qubits, name='control')
q_target = QuantumRegister(operation.num_qubits, name='target')
q_ancillae = None # TODO: add
qc = QuantumCircuit(q_control, q_target)

controlled_circ = QuantumCircuit(q_control, q_target,
name='c_{}'.format(operation.name))
global_phase = 0
if operation.name == 'x' or (
isinstance(operation, controlledgate.ControlledGate) and
operation.base_gate.name == 'x'):
qc.mct(q_control[:] + q_target[:-1], q_target[-1], q_ancillae)
elif operation.name == 'rx':
qc.mcrx(operation.definition.data[0][0].params[0], q_control, q_target[0],
use_basis_gates=True)
elif operation.name == 'ry':
qc.mcry(operation.definition.data[0][0].params[0], q_control, q_target[0],
q_ancillae, mode='noancilla', use_basis_gates=True)
elif operation.name == 'rz':
qc.mcrz(operation.definition.data[0][0].params[0], q_control, q_target[0],
use_basis_gates=True)
controlled_circ.mct(q_control[:] + q_target[:-1], q_target[-1], q_ancillae)
if operation.definition is not None and operation.definition.global_phase:
global_phase += operation.definition.global_phase
else:
bgate = _unroll_gate(operation, ['u1', 'u3', 'cx'])
# now we have a bunch of single qubit rotation gates and cx
for rule in bgate.definition.data:
if rule[0].name == 'u3':
theta, phi, lamb = rule[0].params
basis = ['u1', 'u3', 'x', 'rx', 'ry', 'rz', 'cx']
unrolled_gate = _unroll_gate(operation, basis_gates=basis)
for gate, qreg, _ in unrolled_gate.definition.data:
if gate.name == 'x':
controlled_circ.mct(q_control, q_target[qreg[0].index],
q_ancillae)
elif gate.name == 'rx':
controlled_circ.mcrx(gate.definition.data[0][0].params[0],
q_control, q_target[qreg[0].index],
use_basis_gates=True)
elif gate.name == 'ry':
controlled_circ.mcry(gate.definition.data[0][0].params[0],
q_control, q_target[qreg[0].index],
q_ancillae, mode='noancilla',
use_basis_gates=True)
elif gate.name == 'rz':
controlled_circ.mcrz(gate.definition.data[0][0].params[0],
q_control, q_target[qreg[0].index],
use_basis_gates=True)
elif gate.name == 'u1':
controlled_circ.mcu1(gate.params[0], q_control, q_target[qreg[0].index])
elif gate.name == 'cx':
controlled_circ.mct(q_control[:] + [q_target[qreg[0].index]],
q_target[qreg[1].index],
q_ancillae)
elif gate.name == 'u3':
theta, phi, lamb = gate.params
if phi == -pi / 2 and lamb == pi / 2:
qc.mcrx(theta, q_control, q_target[rule[1][0].index],
use_basis_gates=True)
controlled_circ.mcrx(theta, q_control, q_target[qreg[0].index],
use_basis_gates=True)
elif phi == 0 and lamb == 0:
qc.mcry(theta, q_control, q_target[rule[1][0].index],
q_ancillae, use_basis_gates=True)
controlled_circ.mcry(theta, q_control, q_target[qreg[0].index],
q_ancillae, use_basis_gates=True)
elif theta == 0 and phi == 0:
qc.mcrz(lamb, q_control, q_target[rule[1][0].index],
use_basis_gates=True)
controlled_circ.mcrz(lamb, q_control, q_target[qreg[0].index],
use_basis_gates=True)
else:
qc.mcrz(lamb, q_control, q_target[rule[1][0].index],
use_basis_gates=True)
qc.mcry(theta, q_control, q_target[rule[1][0].index],
q_ancillae, use_basis_gates=True)
qc.mcrz(phi, q_control, q_target[rule[1][0].index],
use_basis_gates=True)
elif rule[0].name == 'u1':
qc.mcu1(rule[0].params[0], q_control, q_target[rule[1][0].index])
elif rule[0].name == 'cx':
qc.mct(q_control[:] + [q_target[rule[1][0].index]], q_target[rule[1][1].index],
q_ancillae)
controlled_circ.mcrz(lamb, q_control, q_target[qreg[0].index],
use_basis_gates=True)
controlled_circ.mcry(theta, q_control, q_target[qreg[0].index],
q_ancillae, use_basis_gates=True)
controlled_circ.mcrz(phi, q_control, q_target[qreg[0].index],
use_basis_gates=True)
else:
raise CircuitError('gate contains non-controllable instructions')

raise CircuitError('gate contains non-controllable instructions: {}'.format(
gate.name))
if gate.definition is not None and gate.definition.global_phase:
global_phase += gate.definition.global_phase
# apply controlled global phase
if ((operation.definition is not None and operation.definition.global_phase) or global_phase):
if len(q_control) < 2:
controlled_circ.u1(operation.definition.global_phase + global_phase, q_control)
else:
controlled_circ.mcu1(operation.definition.global_phase + global_phase,
q_control[:-1], q_control[-1])
if isinstance(operation, controlledgate.ControlledGate):
new_num_ctrl_qubits = num_ctrl_qubits + operation.num_ctrl_qubits
new_ctrl_state = operation.ctrl_state << num_ctrl_qubits | ctrl_state
Expand All @@ -170,11 +188,11 @@ def control(operation: Union[Gate, ControlledGate],
ctrl_substr = ('{0}' * new_num_ctrl_qubits).format('c')
new_name = '{0}{1}'.format(ctrl_substr, base_name)
cgate = controlledgate.ControlledGate(new_name,
qc.num_qubits,
controlled_circ.num_qubits,
operation.params,
label=label,
num_ctrl_qubits=new_num_ctrl_qubits,
definition=qc,
definition=controlled_circ,
ctrl_state=new_ctrl_state)
cgate.base_gate = base_gate
return cgate
Expand All @@ -196,7 +214,7 @@ def _gate_to_circuit(operation):

def _gate_to_dag(operation):
from qiskit.converters.circuit_to_dag import circuit_to_dag
if hasattr(operation, 'definition') and operation.definition:
if hasattr(operation, 'definition') and operation.definition is not None:
return circuit_to_dag(operation.definition)
else:
qr = QuantumRegister(operation.num_qubits)
Expand All @@ -210,5 +228,5 @@ def _unroll_gate(operation, basis_gates):
from qiskit.transpiler.passes import Unroller
unroller = Unroller(basis_gates)
dag = _gate_to_dag(operation)
qc = dag_to_circuit(unroller.run(dag))
return qc.to_gate()
opqc = dag_to_circuit(unroller.run(dag))
return opqc.to_gate()
3 changes: 2 additions & 1 deletion qiskit/circuit/controlledgate.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,5 @@ def __eq__(self, other) -> bool:

def inverse(self) -> 'ControlledGate':
"""Invert this gate by calling inverse on the base gate."""
return self.base_gate.inverse().control(self.num_ctrl_qubits)
return self.base_gate.inverse().control(self.num_ctrl_qubits,
ctrl_state=self.ctrl_state)
1 change: 0 additions & 1 deletion qiskit/circuit/equivalence.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ def _raise_if_shape_mismatch(gate, circuit):

def _rebind_equiv(equiv, query_params):
equiv_params, equiv_circuit = equiv

param_map = dict(zip(equiv_params, query_params))
equiv = equiv_circuit.assign_parameters(param_map, inplace=False)

Expand Down
9 changes: 9 additions & 0 deletions qiskit/circuit/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@
IntegerComparator
Functions on binary variables
+++++++++++++++++++++++++++++
.. autosummary::
:toctree: ../stubs/
QuadraticForm
Particular Quantum Circuits
===========================
Expand Down Expand Up @@ -194,6 +202,7 @@
PolynomialPauliRotations,
IntegerComparator,
WeightedAdder,
QuadraticForm,
)
from .n_local import (
NLocal,
Expand Down
1 change: 1 addition & 0 deletions qiskit/circuit/library/arithmetic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
from .piecewise_linear_pauli_rotations import PiecewiseLinearPauliRotations
from .polynomial_pauli_rotations import PolynomialPauliRotations
from .weighted_adder import WeightedAdder
from .quadratic_form import QuadraticForm
Loading

0 comments on commit e0a9f73

Please sign in to comment.