Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def assert_qasm_is_consistent_with_unitary(val: Any):
"""Uses `val._unitary_` to check `val._qasm_`'s behavior."""
# Only test if qiskit is installed.
try:
import qiskit
except ImportError:
# coverage: ignore
warnings.warn("Skipped assert_qasm_is_consistent_with_unitary because "
"qiskit isn't installed to verify against.")
return
unitary = protocols.unitary(val, None)
if unitary is None:
# Vacuous consistency.
return
if isinstance(val, ops.Operation):
qubits: Sequence[ops.Qid] = val.qubits
op = val
elif isinstance(val, ops.Gate):
qid_shape = protocols.qid_shape(val)
remaining_shape = list(qid_shape)
controls = getattr(val, 'control_qubits', None)
if controls is not None:
for i, q in zip(reversed(range(len(controls))), reversed(controls)):
if q is not None:
remaining_shape.pop(i)
qubits = devices.LineQid.for_qid_shape(remaining_shape)
def assert_has_consistent_trace_distance_bound(val: Any) -> None:
u = protocols.unitary(val, default=None)
val_from_trace = protocols.trace_distance_bound(val)
assert 0.0 <= val_from_trace <= 1.0
if u is not None:
class Unitary:
def _unitary_(self):
return u
val_from_unitary = protocols.trace_distance_bound(Unitary())
assert val_from_trace >= val_from_unitary or np.isclose(
val_from_trace, val_from_unitary)
def _merge_rotations(
self,
qubit: ops.QubitId,
operations: Iterable[ops.Operation]
) -> List[ops.Operation]:
matrix = linalg.dot(
np.eye(2, dtype=np.complex128),
*reversed([protocols.unitary(op) for op in operations]))
out_gates = single_qubit_matrix_to_native_gates(matrix, self.tolerance)
return [gate(qubit) for gate in out_gates]
def fallback(op):
if len(op.qubits) not in [1, 2]:
return NotImplemented
mat = protocols.unitary(op, None)
if mat is None:
return NotImplemented
if len(op.qubits) == 1:
return QasmUGate.from_matrix(mat).on(*op.qubits)
return QasmTwoQubitGate.from_matrix(mat).on(*op.qubits)
def _convert_one(self, op: ops.Operation) -> ops.OP_TREE:
# Don't change if it's already a ops.PauliStringPhasor
if isinstance(op, ops.PauliStringPhasor):
return op
if (self.keep_clifford
and isinstance(op, ops.GateOperation)
and isinstance(op.gate, ops.SingleQubitCliffordGate)):
return op
# Single qubit gate with known matrix?
if len(op.qubits) == 1:
mat = protocols.unitary(op, None)
if mat is not None:
return self._matrix_to_pauli_string_phasors(mat, op.qubits[0])
# Just let it be?
if self.ignore_failures:
return op
raise TypeError("Don't know how to work with {!r}. "
"It isn't a 1-qubit operation with a known unitary "
"effect.".format(op))
def _convert_one(self, op: ops.Operation) -> ops.OP_TREE:
# Single qubit gate with known matrix?
if len(op.qubits) == 1:
mat = protocols.unitary(op, None)
if mat is not None:
cliff_op = self._matrix_to_clifford_op(mat, op.qubits[0])
if cliff_op is not None:
return cliff_op
return NotImplemented
def _rewrite(self, operations: List[ops.Operation]
) -> Optional[ops.OP_TREE]:
if not operations:
return None
q = operations[0].qubits[0]
# Custom rewriter?
if self._rewriter is not None:
return self._rewriter(operations)
unitary = linalg.dot(*(protocols.unitary(op)
for op in operations[::-1]))
# Custom synthesizer?
if self._synthesizer is not None:
return self._synthesizer(q, unitary)
# Just use the default.
return ops.SingleQubitMatrixGate(unitary).on(q)
def _unitary_(self) -> Union[np.ndarray, NotImplementedType]:
if self._name == 'X':
return protocols.unitary(common_gates.X)
elif self._name == 'Y':
return protocols.unitary(common_gates.Y)
else:
return protocols.unitary(common_gates.Z)
start_frontier = {q: frontier[q] for q in g}
end_frontier = circuit.reachable_frontier_from(start_frontier)
mergeable_ops = circuit.findall_operations_between(start_frontier,
end_frontier)
# Advance frontier.
for q, v in end_frontier.items():
frontier[q] = v
# Fold reachable operations into a single group matrix.
group_matrix = np.eye(1 << len(g)).reshape((2, 2) * len(g))
if mergeable_ops:
any_group_matrices = True
for _, op in mergeable_ops:
group_matrix = linalg.targeted_left_multiply(
left_matrix=protocols.unitary(op).reshape(
(2, 2) * len(op.qubits)),
right_target=group_matrix,
target_axes=[grouping.loc(q)[1] for q in op.qubits])
group_matrices.append(np.transpose(group_matrix.reshape(
1 << len(g), 1 << len(g))))
# Scan for reachable CZ operations between groups.
end_frontier = circuit.reachable_frontier_from(
frontier,
is_blocker=lambda op: grouping.all_in_same_group(*op.qubits))
cz_ops = circuit.findall_operations_between(frontier, end_frontier)
# Advance frontier.
frontier = end_frontier
# List out qubit index pairs for each CZ.