A framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The transformers module provides tools for transforming and optimizing quantum circuits, including analytical decompositions, target gateset compilation, and circuit structure manipulation.
def single_qubit_matrix_to_gates(matrix: np.ndarray, tolerance: float = 1e-10) -> List['cirq.Operation']:
"""Decompose single-qubit unitary matrix into elementary gates.
Args:
matrix: 2x2 unitary matrix to decompose
tolerance: Numerical tolerance for decomposition
Returns:
List of single-qubit operations implementing the matrix
"""
def single_qubit_matrix_to_pauli_rotations(matrix: np.ndarray, tolerance: float = 1e-10) -> List['cirq.Operation']:
"""Decompose single-qubit matrix into Pauli rotations."""
def single_qubit_matrix_to_phased_x_z(matrix: np.ndarray, tolerance: float = 1e-10) -> List['cirq.Operation']:
"""Decompose into phased X and Z rotations."""
def single_qubit_matrix_to_phxz(matrix: np.ndarray, tolerance: float = 1e-10) -> 'cirq.PhasedXZGate':
"""Decompose into single PhasedXZ gate."""
def single_qubit_op_to_framed_phase_form(op: 'cirq.Operation') -> List['cirq.Operation']:
"""Convert single-qubit operation to framed phase form."""def two_qubit_matrix_to_cz_operations(matrix: np.ndarray,
qubits: Sequence['cirq.Qid'],
tolerance: float = 1e-10) -> List['cirq.Operation']:
"""Decompose two-qubit unitary into CZ-based operations.
Args:
matrix: 4x4 unitary matrix
qubits: Target qubits for decomposition
tolerance: Numerical tolerance
Returns:
List of operations using single-qubit gates and CZ
"""
def two_qubit_matrix_to_sqrt_iswap_operations(
q0: 'cirq.Qid',
q1: 'cirq.Qid',
mat: np.ndarray,
*,
required_sqrt_iswap_count: int = None,
use_sqrt_iswap_inv: bool = False,
atol: float = 1e-8,
check_preconditions: bool = True,
clean_operations: bool = False,
) -> Sequence['cirq.Operation']:
"""Decompose two-qubit unitary into √iSWAP-based operations.
Args:
q0: First qubit
q1: Second qubit
mat: 4x4 unitary matrix to decompose
required_sqrt_iswap_count: Required number of √iSWAP gates (optional)
use_sqrt_iswap_inv: Whether to use √iSWAP† gates
atol: Absolute tolerance for decomposition
check_preconditions: Whether to validate input matrix
clean_operations: Whether to clean up negligible operations
Returns:
Sequence of operations implementing the matrix
"""
def two_qubit_matrix_to_ion_operations(matrix: np.ndarray,
qubits: Sequence['cirq.Qid'],
tolerance: float = 1e-10) -> List['cirq.Operation']:
"""Decompose for ion trap quantum computers using MS gates."""
def parameterized_2q_op_to_sqrt_iswap_operations(op: 'cirq.Operation',
tolerance: float = 1e-10) -> List['cirq.Operation']:
"""Decompose parameterized two-qubit operation to √iSWAP gates."""def three_qubit_matrix_to_operations(matrix: np.ndarray,
qubits: Sequence['cirq.Qid'],
tolerance: float = 1e-10) -> List['cirq.Operation']:
"""Decompose three-qubit unitary matrix.
Args:
matrix: 8x8 unitary matrix
qubits: Target qubits
tolerance: Numerical tolerance
Returns:
Decomposed operations
"""
def decompose_multi_controlled_x(qubits: Sequence['cirq.Qid'],
control_values: Sequence[int] = None,
work_qubits: Sequence['cirq.Qid'] = None) -> List['cirq.Operation']:
"""Decompose multi-controlled X gate."""
def decompose_multi_controlled_rotation(angles: Sequence[float],
qubits: Sequence['cirq.Qid'],
control_values: Sequence[int] = None) -> List['cirq.Operation']:
"""Decompose multi-controlled rotation gate."""class CompilationTargetGateset:
"""Base class for target gatesets in compilation."""
def __init__(self, *, name: str = None,
unroll_circuit_op: bool = True) -> None:
"""Initialize compilation target gateset."""
def decompose_to_target_gateset(self, op: 'cirq.Operation',
moment_index: int) -> 'cirq.OP_TREE':
"""Decompose operation to target gateset."""
def preprocess_transformers(self) -> List['cirq.TRANSFORMER']:
"""Get preprocessing transformers."""
def postprocess_transformers(self) -> List['cirq.TRANSFORMER']:
"""Get postprocessing transformers."""
class TwoQubitCompilationTargetGateset(CompilationTargetGateset):
"""Target gateset for two-qubit gate compilation."""
def __init__(self, gate: 'cirq.Gate', **kwargs) -> None:
"""Initialize with specific two-qubit gate."""
class CZTargetGateset(TwoQubitCompilationTargetGateset):
"""Target gateset using CZ gates."""
def __init__(self, *, atol: float = 1e-8, **kwargs) -> None:
"""Initialize CZ target gateset."""
class SqrtIswapTargetGateset(TwoQubitCompilationTargetGateset):
"""Target gateset using √iSWAP gates."""
def __init__(self, *, atol: float = 1e-8, **kwargs) -> None:
"""Initialize √iSWAP target gateset."""def optimize_for_target_gateset(circuit: 'cirq.Circuit',
gateset: CompilationTargetGateset,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Optimize circuit for target gateset.
Args:
circuit: Input circuit to optimize
gateset: Target gateset for compilation
context: Transformation context
Returns:
Optimized circuit using only target gateset
"""
def create_transformer_with_kwargs(transformer: 'cirq.TRANSFORMER', **kwargs) -> 'cirq.TRANSFORMER':
"""Create transformer with additional keyword arguments."""def align_left(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Align circuit operations to the left (earliest possible moments).
Args:
circuit: Circuit to align
context: Transformation context
Returns:
Left-aligned circuit
"""
def align_right(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Align circuit operations to the right (latest possible moments)."""
def stratified_circuit(circuit: 'cirq.Circuit',
categories: Sequence[Callable[['cirq.Operation'], bool]] = None,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Create stratified circuit organizing operations by categories."""def drop_empty_moments(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Remove empty moments from circuit.
Args:
circuit: Input circuit
context: Transformation context
Returns:
Circuit with empty moments removed
"""
def merge_moments(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Merge adjacent compatible moments."""
def drop_negligible_operations(circuit: 'cirq.Circuit',
atol: float = 1e-8,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Remove operations with negligible effect."""
def is_negligible_turn(turn: Union[float, sympy.Expr], atol: float = 1e-8) -> bool:
"""Check if rotation angle is negligible."""def expand_composite(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Expand composite operations in circuit.
Args:
circuit: Circuit with composite operations
context: Transformation context
Returns:
Circuit with composite operations expanded
"""
def unroll_circuit_op(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None,
deep: bool = True,
tags_to_check: Sequence = ()) -> 'cirq.Circuit':
"""Unroll CircuitOperation instances in circuit."""
def unroll_circuit_op_greedy_earliest(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Unroll circuit operations using greedy earliest strategy."""
def unroll_circuit_op_greedy_frontier(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Unroll circuit operations using greedy frontier strategy."""def merge_single_qubit_gates_to_phased_x_and_z(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Merge adjacent single-qubit gates into PhasedX and Z rotations.
Args:
circuit: Input circuit
context: Transformation context
Returns:
Circuit with merged single-qubit gates
"""
def merge_single_qubit_gates_to_phxz(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Merge single-qubit gates into PhasedXZ gates."""
def merge_single_qubit_moments_to_phxz(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Merge single-qubit gates across moments into PhasedXZ."""
def merge_single_qubit_gates_to_phxz_symbolized(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Symbolic merging of single-qubit gates."""def merge_k_qubit_unitaries(circuit: 'cirq.Circuit',
k: int = 2,
context: 'cirq.TransformerContext' = None,
merged_gate_tolerance: float = 1e-10) -> 'cirq.Circuit':
"""Merge adjacent k-qubit unitary operations.
Args:
circuit: Input circuit
k: Number of qubits for unitary merging
context: Transformation context
merged_gate_tolerance: Tolerance for gate merging
Returns:
Circuit with merged k-qubit unitaries
"""
def merge_k_qubit_unitaries_to_circuit_op(circuit: 'cirq.Circuit',
k: int = 2,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Merge k-qubit unitaries into CircuitOperations."""
def merge_operations(circuit: 'cirq.Circuit',
merge_func: Callable = None,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Merge operations using custom merge function."""
def merge_operations_to_circuit_op(circuit: 'cirq.Circuit',
merge_func: Callable = None,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Merge operations into CircuitOperations."""def defer_measurements(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Defer all measurements to the end of the circuit.
Args:
circuit: Circuit with measurements
context: Transformation context
Returns:
Circuit with measurements moved to end
"""
def dephase_measurements(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Add dephasing before measurements."""
def drop_terminal_measurements(circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Remove measurements at the end of circuit."""
def synchronize_terminal_measurements(circuit: 'cirq.Circuit',
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Synchronize all terminal measurements to same moment."""def eject_phased_paulis(circuit: 'cirq.Circuit',
eject_parameterized: bool = False,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Eject phased Pauli gates to the end of the circuit.
Args:
circuit: Input circuit
eject_parameterized: Whether to eject parameterized Paulis
context: Transformation context
Returns:
Circuit with Pauli gates ejected
"""
def eject_z(circuit: 'cirq.Circuit',
eject_parameterized: bool = False,
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Eject Z gates to the end of circuit."""TRANSFORMER = Callable[['cirq.Circuit', 'cirq.TransformerContext'], 'cirq.Circuit']
"""Type for circuit transformer functions."""
def transformer(func: TRANSFORMER) -> TRANSFORMER:
"""Decorator to mark function as transformer."""
class TransformerContext:
"""Context for circuit transformations."""
def __init__(self, *, logger: 'TransformerLogger' = None,
deep: bool = False,
tags_to_ignore: Sequence = ()) -> None:
"""Initialize transformer context."""
@property
def logger(self) -> 'TransformerLogger':
"""Logger for transformation steps."""
def with_deep(self, deep: bool) -> 'TransformerContext':
"""Return context with different deep setting."""
class TransformerLogger:
"""Logger for circuit transformations."""
def __init__(self, *, print_out: bool = True) -> None:
"""Initialize transformer logger."""
def log(self, message: str, level: 'LogLevel' = 'LogLevel.INFO') -> None:
"""Log transformation message."""
class LogLevel(enum.Enum):
"""Logging levels for transformers."""
DEBUG = 0
INFO = 1
WARNING = 2
ERROR = 3def map_moments(circuit: 'cirq.Circuit',
map_func: Callable[['cirq.Moment', int], 'cirq.OP_TREE'],
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Apply function to each moment in circuit.
Args:
circuit: Input circuit
map_func: Function to apply to each moment
context: Transformation context
Returns:
Transformed circuit
"""
def map_operations(circuit: 'cirq.Circuit',
map_func: Callable[['cirq.Operation', int], 'cirq.OP_TREE'],
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Apply function to each operation in circuit."""
def map_operations_and_unroll(circuit: 'cirq.Circuit',
map_func: Callable[['cirq.Operation', int], 'cirq.OP_TREE'],
context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit':
"""Map operations and unroll results."""import cirq
import numpy as np
print("=== Circuit Alignment ===")
# Create circuit with operations that can be rearranged
qubits = cirq.LineQubit.range(3)
circuit = cirq.Circuit([
cirq.X(qubits[0]),
cirq.Y(qubits[1]),
cirq.Z(qubits[2]),
cirq.H(qubits[0]),
cirq.CNOT(qubits[0], qubits[1])
])
print("Original circuit:")
print(circuit)
# Align left (earliest possible moments)
left_aligned = cirq.align_left(circuit)
print("\nLeft-aligned circuit:")
print(left_aligned)
# Align right (latest possible moments)
right_aligned = cirq.align_right(circuit)
print("\nRight-aligned circuit:")
print(right_aligned)import cirq
import numpy as np
print("=== Single-Qubit Gate Merging ===")
# Create circuit with many single-qubit gates
qubit = cirq.LineQubit(0)
circuit = cirq.Circuit([
cirq.H(qubit),
cirq.X(qubit)**0.5,
cirq.Z(qubit)**0.25,
cirq.Y(qubit)**0.1,
cirq.S(qubit)
])
print(f"Original circuit ({len(circuit)} moments):")
print(circuit)
# Merge into PhasedXZ gates
merged_circuit = cirq.merge_single_qubit_gates_to_phxz(circuit)
print(f"\nMerged circuit ({len(merged_circuit)} moments):")
print(merged_circuit)
# Verify circuits are equivalent
simulator = cirq.Simulator()
original_state = simulator.simulate(circuit).final_state_vector
merged_state = simulator.simulate(merged_circuit).final_state_vector
print(f"States equivalent: {np.allclose(original_state, merged_state)}")import cirq
print("=== Target Gateset Compilation ===")
# Create circuit with various two-qubit gates
qubits = cirq.LineQubit.range(2)
circuit = cirq.Circuit([
cirq.H(qubits[0]),
cirq.CNOT(qubits[0], qubits[1]),
cirq.SWAP(qubits[0], qubits[1]),
cirq.CZ(qubits[0], qubits[1])**0.5
])
print("Original circuit:")
print(circuit)
# Compile to CZ target gateset
cz_gateset = cirq.CZTargetGateset()
cz_circuit = cirq.optimize_for_target_gateset(circuit, cz_gateset)
print("\nCompiled to CZ gateset:")
print(cz_circuit)
# Compile to √iSWAP target gateset
iswap_gateset = cirq.SqrtIswapTargetGateset()
iswap_circuit = cirq.optimize_for_target_gateset(circuit, iswap_gateset)
print("\nCompiled to √iSWAP gateset:")
print(iswap_circuit)import cirq
import numpy as np
print("=== Matrix Decomposition ===")
# Create arbitrary two-qubit unitary
theta = np.pi / 3
phi = np.pi / 4
matrix = np.array([
[np.cos(theta), -np.sin(theta), 0, 0],
[np.sin(theta), np.cos(theta), 0, 0],
[0, 0, np.cos(phi), -np.sin(phi)],
[0, 0, np.sin(phi), np.cos(phi)]
])
qubits = cirq.LineQubit.range(2)
# Decompose to CZ operations
cz_ops = cirq.two_qubit_matrix_to_cz_operations(matrix, qubits)
print(f"CZ decomposition ({len(cz_ops)} operations):")
for op in cz_ops:
print(f" {op}")
# Decompose to √iSWAP operations
iswap_ops = cirq.two_qubit_matrix_to_sqrt_iswap_operations(matrix, qubits)
print(f"\n√iSWAP decomposition ({len(iswap_ops)} operations):")
for op in iswap_ops:
print(f" {op}")
# Verify decomposition
circuit_cz = cirq.Circuit(cz_ops)
circuit_iswap = cirq.Circuit(iswap_ops)
print(f"\nCZ decomposition unitary matches: {np.allclose(matrix, cirq.unitary(circuit_cz))}")
print(f"√iSWAP decomposition unitary matches: {np.allclose(matrix, cirq.unitary(circuit_iswap))}")import cirq
print("=== Measurement Transformations ===")
# Create circuit with measurements throughout
qubits = cirq.LineQubit.range(3)
circuit = cirq.Circuit([
cirq.H(qubits[0]),
cirq.measure(qubits[0], key='early'),
cirq.CNOT(qubits[0], qubits[1]),
cirq.H(qubits[1]),
cirq.measure(qubits[1], key='middle'),
cirq.CNOT(qubits[1], qubits[2]),
cirq.measure(qubits[2], key='late')
])
print("Original circuit:")
print(circuit)
# Defer measurements to end
deferred_circuit = cirq.defer_measurements(circuit)
print("\nDeferred measurements:")
print(deferred_circuit)
# Drop terminal measurements
no_measure_circuit = cirq.drop_terminal_measurements(deferred_circuit)
print("\nWithout terminal measurements:")
print(no_measure_circuit)Transform logical circuits to physical hardware by mapping logical qubits to physical qubits and inserting SWAP operations as needed.
class RouteCQC:
"""Route circuits using the Configurable Quantum Computer (CQC) routing algorithm."""
def __init__(self, router_class: type, router_args: dict = None) -> None: ...
def __call__(self, circuit: 'cirq.Circuit', device_graph: 'networkx.Graph') -> 'cirq.Circuit': ...
def routed_circuit_with_mapping(
circuit: 'cirq.Circuit',
device_graph: 'networkx.Graph',
initial_mapper: 'AbstractInitialMapper' = None,
router: 'RouteCQC' = None
) -> Tuple['cirq.Circuit', Dict['cirq.Qid', 'cirq.Qid']]:
"""Route a circuit and return both the routed circuit and the qubit mapping."""class AbstractInitialMapper:
"""Abstract base for initial qubit mapping strategies."""
def initial_mapping(self, circuit: 'cirq.Circuit', device_graph: 'networkx.Graph') -> Dict['cirq.Qid', 'cirq.Qid']: ...
class HardCodedInitialMapper(AbstractInitialMapper):
"""Use a pre-defined mapping between logical and physical qubits."""
def __init__(self, initial_mapping: Dict['cirq.Qid', 'cirq.Qid']) -> None: ...
class LineInitialMapper(AbstractInitialMapper):
"""Map logical qubits to a line of physical qubits."""class MappingManager:
"""Manage the mapping between logical and physical qubits during routing."""
def __init__(self, device_graph: 'networkx.Graph', initial_mapping: Dict['cirq.Qid', 'cirq.Qid'] = None) -> None: ...
def current_mapping(self) -> Dict['cirq.Qid', 'cirq.Qid']: ...
def apply_swap(self, swap_op: 'cirq.Operation') -> None: ...
def map_clean_and_borrowable_qubits(
circuit: 'cirq.Circuit',
qubit_map: Dict['cirq.Qid', 'cirq.Qid'],
clean_qubits: Set['cirq.Qid'] = None,
borrowable_qubits: Set['cirq.Qid'] = None
) -> 'cirq.Circuit':
"""Map qubits in a circuit, distinguishing between clean and borrowable ancilla qubits."""Advanced gauge-based transformations for two-qubit gate optimization and error mitigation.
class Gauge:
"""Abstract gauge transformation."""
def weight(self) -> float: ...
def sample(self, gate: 'cirq.Gate', prng: np.random.Generator) -> 'cirq.Gate': ...
class ConstantGauge(Gauge):
"""Gauge that always applies the same transformation."""
def __init__(self, gauge_map: Dict['cirq.Gate', 'cirq.Gate']) -> None: ...
class GaugeSelector:
"""Select gauges based on various criteria."""
def __init__(self, gauges: List[Gauge], selection_strategy: str = 'uniform') -> None: ...
class GaugeTransformer:
"""Apply gauge transformations to circuits."""
def __init__(self, gauge_selector: GaugeSelector, num_gauge_selections: int = 1) -> None: ...class CZGaugeTransformer(GaugeTransformer):
"""Gauge transformer for CZ-based circuits."""
class ISWAPGaugeTransformer(GaugeTransformer):
"""Gauge transformer for iSWAP-based circuits."""
class SqrtCZGaugeTransformer(GaugeTransformer):
"""Gauge transformer for √CZ-based circuits."""
class SqrtISWAPGaugeTransformer(GaugeTransformer):
"""Gauge transformer for √iSWAP-based circuits."""
class SpinInversionGaugeTransformer(GaugeTransformer):
"""Apply spin inversion gauge transformations."""
class CPhaseGaugeTransformer(GaugeTransformer):
"""Gauge transformer for controlled-phase gates."""Advanced transformers for noise modeling and error mitigation techniques.
class DepolarizingNoiseTransformer:
"""Add depolarizing noise to circuit operations."""
def __init__(self, p_single: float = 0.001, p_two: float = 0.01) -> None: ...
def __call__(self, circuit: 'cirq.Circuit', context: 'cirq.TransformerContext' = None) -> 'cirq.Circuit': ...
class RandomizedMeasurements:
"""Implement randomized measurement protocols for error mitigation."""
def __init__(self, randomization_type: str = 'pauli') -> None: ...
def add_dynamical_decoupling(
circuit: 'cirq.Circuit',
decoupling_gates: List['cirq.Gate'] = None,
insertion_strategy: str = 'periodic'
) -> 'cirq.Circuit':
"""Add dynamical decoupling sequences to idle periods in the circuit."""Utilities for managing operation tags and symbolic parameters.
def index_tags(circuit: 'cirq.Circuit', tag_class: type = None) -> 'cirq.Circuit':
"""Add index tags to operations for tracking and analysis."""
def remove_tags(circuit: 'cirq.Circuit', tag_classes: List[type] = None) -> 'cirq.Circuit':
"""Remove specified tags from all operations in the circuit."""
def toggle_tags(circuit: 'cirq.Circuit', tag_class: type, condition: Callable = None) -> 'cirq.Circuit':
"""Toggle tags on operations based on a condition function."""
class SymbolizeTag:
"""Tag for marking operations that should be symbolized."""
def symbolize_single_qubit_gates_by_indexed_tags(circuit: 'cirq.Circuit') -> 'cirq.Circuit':
"""Convert single-qubit gates with indexed tags to symbolic parameters."""This comprehensive transformation framework enables circuit optimization, compilation to target hardware, routing for physical devices, advanced gauge transformations, noise modeling, and symbolic manipulation for improved performance and hardware compatibility.
Install with Tessl CLI
npx tessl i tessl/pypi-cirq