Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
abraham.asfaw committed May 12, 2020
2 parents cd8291d + 17a9390 commit b3042f3
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 16 deletions.
6 changes: 4 additions & 2 deletions qiskit/extensions/unitary.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,10 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
"""
cmat = _compute_control_matrix(self.to_matrix(), num_ctrl_qubits)
iso = isometry.Isometry(cmat, 0, 0)
return ControlledGate('c-unitary', self.num_qubits + num_ctrl_qubits, cmat,
definition=iso.definition, label=label)
cunitary = ControlledGate('c-unitary', self.num_qubits + num_ctrl_qubits, cmat,
definition=iso.definition, label=label)
cunitary.base_gate.label = self.label
return cunitary

def qasm(self):
""" The qasm for a custom unitary gate
Expand Down
4 changes: 2 additions & 2 deletions qiskit/qobj/converters/pulse_instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def convert_set_frequency(self, shift, instruction):
'name': 'setf',
't0': shift+instruction.start_time,
'ch': instruction.channel.name,
'frequency': instruction.frequency
'frequency': instruction.frequency / 1e9
}
return self._qobj_model(**command_dict)

Expand Down Expand Up @@ -532,7 +532,7 @@ def convert_set_frequency(self, instruction):
"""
t0 = instruction.t0
channel = self.get_channel(instruction.ch)
frequency = instruction.frequency
frequency = instruction.frequency * 1e9

if isinstance(frequency, str):
frequency_expr = parse_string_expr(frequency, partial_binding=False)
Expand Down
19 changes: 12 additions & 7 deletions qiskit/quantum_info/operators/symplectic/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,18 @@ def random_clifford(num_qubits, seed=None):
_fill_tril(delta1, rng)
_fill_tril(delta2, rng)

# For large num_qubits numpy.inv function called below can
# return invalid output leading to a non-symplectic Clifford
# being generated. This can be prevented by manually forcing
# block inversion of the matrix.
block_inverse_threshold = 50

# Compute stabilizer table
zero = np.zeros((num_qubits, num_qubits), dtype=np.int8)
prod1 = np.matmul(gamma1, delta1) % 2
prod2 = np.matmul(gamma2, delta2) % 2
inv1 = _inverse_tril(delta1).transpose()
inv2 = _inverse_tril(delta2).transpose()
inv1 = _inverse_tril(delta1, block_inverse_threshold).transpose()
inv2 = _inverse_tril(delta2, block_inverse_threshold).transpose()
table1 = np.block([[delta1, zero], [prod1, inv1]])
table2 = np.block([[delta2, zero], [prod2, inv2]])

Expand Down Expand Up @@ -197,7 +203,7 @@ def _fill_tril(mat, rng, symmetric=False):
mat[(cols, rows)] = vals


def _inverse_tril(mat):
def _inverse_tril(mat, block_inverse_threshold):
"""Invert a lower-triangular matrix with unit diagonal."""
# Optimized inversion function for low dimensions
dim = mat.shape[0]
Expand All @@ -221,8 +227,7 @@ def _inverse_tril(mat):
# For higher dimensions we use Numpy's inverse function
# however this function tends to fail and result in a non-symplectic
# final matrix if n is too large.
max_np_inv = 150
if dim <= max_np_inv:
if dim <= block_inverse_threshold:
return np.linalg.inv(mat).astype(np.int8) % 2

# For very large matrices we divide the matrix into 4 blocks of
Expand All @@ -232,8 +237,8 @@ def _inverse_tril(mat):
# call the inverse function recursively to compute inv(A) and invD

dim1 = dim // 2
mat_a = _inverse_tril(mat[0:dim1, 0:dim1])
mat_d = _inverse_tril(mat[dim1:dim, dim1:dim])
mat_a = _inverse_tril(mat[0:dim1, 0:dim1], block_inverse_threshold)
mat_d = _inverse_tril(mat[dim1:dim, dim1:dim], block_inverse_threshold)
mat_c = np.matmul(np.matmul(mat_d, mat[dim1:dim, 0:dim1]), mat_a)
inv = np.block([[mat_a, np.zeros((dim1, dim - dim1), dtype=int)], [mat_c, mat_d]])
return inv % 2
6 changes: 6 additions & 0 deletions releasenotes/notes/bugfix-set-frequency-29608d213a8cbece.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
Fixed the SI unit conversion for :py:class:`qiskit.pulse.SetFrequency`. The
``SetFrequency`` instruction should be in Hz on the frontend and has to be
converted to GHz when ``SetFrequency`` is converted to ``PulseQobjInstruction``.
4 changes: 2 additions & 2 deletions test/python/qobj/test_pulse_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def test_frame_change(self):
def test_set_frequency(self):
"""Test converted qobj from SetFrequency."""
converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2)
instruction = SetFrequency(8.0, DriveChannel(0))
instruction = SetFrequency(8.0e9, DriveChannel(0))

valid_qobj = PulseQobjInstruction(
name='setf',
Expand Down Expand Up @@ -302,7 +302,7 @@ def test_frame_change(self):

def test_set_frequency(self):
"""Test converted qobj from FrameChangeInstruction."""
instruction = SetFrequency(8.0, DriveChannel(0))
instruction = SetFrequency(8.0e9, DriveChannel(0))

qobj = PulseQobjInstruction(name='setf', ch='d0', t0=0, frequency=8.0)
converted_instruction = self.converter(qobj)
Expand Down
4 changes: 2 additions & 2 deletions test/python/qobj/test_qobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def setUp(self):
PulseQobjInstruction(name='fc', t0=5, ch='d0', phase='P1'),
PulseQobjInstruction(name='pv', t0=10, ch='d0', val=0.1 + 0.0j),
PulseQobjInstruction(name='pv', t0=10, ch='d0', val='P1'),
PulseQobjInstruction(name='sf', t0=10, ch='d0', frequency=8.),
PulseQobjInstruction(name='setf', t0=10, ch='d0', frequency=8.0),
PulseQobjInstruction(name='acquire', t0=15, duration=5,
qubits=[0], memory_slot=[0],
kernels=[
Expand Down Expand Up @@ -265,7 +265,7 @@ def setUp(self):
{'name': 'fc', 't0': 5, 'ch': 'd0', 'phase': 'P1'},
{'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 0.1+0j},
{'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 'P1'},
{'name': 'sf', 't0': 10, 'ch': 'd0', 'frequency': 8.0},
{'name': 'setf', 't0': 10, 'ch': 'd0', 'frequency': 8.0},
{'name': 'acquire', 't0': 15, 'duration': 5,
'qubits': [0], 'memory_slot': [0],
'kernels': [{'name': 'boxcar',
Expand Down
2 changes: 1 addition & 1 deletion test/python/quantum_info/operators/test_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class TestRandomClifford(QiskitTestCase):
@combine(num_qubits=[1, 2, 3, 4, 5, 10, 50, 100, 150, 211])
def test_valid(self, num_qubits):
"""Test random_clifford {num_qubits}-qubits."""
seed = 42
seed = 213
value = random_clifford(num_qubits, seed=seed)
with self.subTest(msg='Test type'):
self.assertIsInstance(value, Clifford)
Expand Down

0 comments on commit b3042f3

Please sign in to comment.