merlin.builder.circuit_builder module
Circuit builder for constructing quantum circuits declaratively.
- class merlin.builder.circuit_builder.Any(*args, **kwargs)
Bases:
objectSpecial type indicating an unconstrained type.
Any is compatible with every type.
Any assumed to have all methods.
All values assumed to be instances of Any.
Note that all the above statements are true from the point of view of static type checkers. At runtime, Any should not be used with instance checks.
- class merlin.builder.circuit_builder.BeamSplitter(targets, theta_role=ParameterRole.FIXED, theta_value=0.7854, phi_role=ParameterRole.FIXED, phi_value=0.0, theta_name=None, phi_name=None)
Bases:
objectBeam splitter description.
- get_params()
Describe which phase shifter angles should be exposed as parameters.
- Return type:
dict[str,Any]
- Returns:
Dict[str, Any]: Parameter placeholders keyed by their symbolic names.
-
phi_name:
Optional[str] = None
-
phi_role:
ParameterRole= 'fixed'
-
phi_value:
float= 0.0
-
targets:
tuple
-
theta_name:
Optional[str] = None
-
theta_role:
ParameterRole= 'fixed'
-
theta_value:
float= 0.7854
- class merlin.builder.circuit_builder.Circuit(n_modes, components=<factory>, metadata=<factory>)
Bases:
objectSimple circuit container.
- add(component)
Append a component and return the circuit for chained calls.
- Return type:
- Args:
component: Circuit element (rotation, beam splitter, measurement, etc.).
- Returns:
Circuit:
selfto support fluent-style chaining.
- clear()
Remove every component and metadata entry from the circuit.
- property depth: int
Estimate logical depth by summing component depths when available.
- get_parameters()
Collect parameter placeholders exposed by each component.
- Return type:
dict[str,Any]
- Returns:
Dict[str, Any]: Mapping from parameter name to default value (or
None).
-
n_modes:
int
- property num_components: int
Return the count of registered components.
- class merlin.builder.circuit_builder.CircuitBuilder(n_modes)
Bases:
objectBuilder for quantum circuits using a declarative API.
- add_angle_encoding(modes=None, name=None, *, scale=1.0, subset_combinations=False, max_order=None)
Convenience method for angle-based input encoding.
- Return type:
- Args:
modes: Optional list of circuit modes to target. Defaults to all modes. name: Prefix used for generated input parameters. Defaults to
"px". scale: Global scaling factor applied before angle mapping. subset_combinations: WhenTrue, generate higher-order featurecombinations (up to
max_order) similar to the legacyFeatureEncoder.- max_order: Optional cap on the size of feature combinations when
subset_combinationsis enabled.Noneuses all orders.
- Returns:
CircuitBuilder:
selffor fluent chaining.
- add_entangling_layer(modes=None, *, trainable=True, model='mzi', name=None, trainable_inner=None, trainable_outer=None)
Add an entangling layer spanning a range of modes.
- Return type:
- Args:
- modes: Optional list describing the span.
Nonetargets all modes; one element targets
modes[0]through the final mode; two elements target the inclusive range[modes[0], modes[1]].
trainable: Whether internal phase shifters should be trainable. model:
"mzi"or"bell"to select the internal interferometer template. name: Optional prefix used for generated parameter names. trainable_inner: Override for the internal (between-beam splitter) phase shifters. trainable_outer: Override for the output phase shifters at the exit of the interferometer.- modes: Optional list describing the span.
- Raises:
ValueError: If the provided modes are invalid or span fewer than two modes.
- Returns:
CircuitBuilder:
selffor fluent chaining.
- add_rotations(modes=None, *, axis='z', trainable=False, as_input=False, angle=None, value=None, name=None, role=None)
Add one or multiple rotations across the provided modes.
- Return type:
- Args:
modes: Single mode, list of modes, module group or
None(all modes). axis: Axis of rotation for each inserted phase shifter. trainable: Promote the rotations to trainable parameters (legacy flag). as_input: Mark the rotations as input-driven parameters (legacy flag). angle: Optional fixed value for the rotations (alias ofvalue). value: Optional fixed value for the rotations (alias ofangle). name: Optional stem used for generated parameter names. role: ExplicitParameterRoletaking precedence over other flags.- Returns:
CircuitBuilder:
selffor fluent chaining.
- add_superpositions(targets=None, *, depth=1, theta=0.785398, phi=0.0, trainable=None, trainable_theta=None, trainable_phi=None, modes=None, name=None)
Add one or more superposition (beam splitter) components.
- Return type:
- Args:
- targets: Tuple or list of tuples describing explicit mode pairs. When
omitted, nearest neighbours over
modes(or all modes) are used.
depth: Number of sequential passes to apply (
>=1). theta: Baseline mixing angle for fixed beam splitters. phi: Baseline relative phase for fixed beam splitters. trainable: Convenience flag to mark boththetaandphitrainable. trainable_theta: Whether the mixing angle should be trainable. trainable_phi: Whether the relative phase should be trainable. modes: Optional mode list/module group used whentargetsis omitted. name: Optional stem used for generated parameter names.- Returns:
CircuitBuilder:
selffor fluent chaining.
- property angle_encoding_specs: dict[str, dict[str, Any]]
Return metadata describing configured angle encodings.
- Returns:
Dict[str, Dict[str, Any]]: Mapping from encoding prefix to combination metadata.
- build()
Build and return the circuit.
- Return type:
- Returns:
Circuit: Circuit instance populated with components.
- classmethod from_circuit(circuit)
Create a builder from an existing circuit.
- Return type:
- Args:
circuit: Circuit object whose components should seed the builder.
- Returns:
CircuitBuilder: A new builder instance wrapping the provided circuit.
- property input_parameter_prefixes: list[str]
Expose the order-preserving set of input prefixes.
- Returns:
List[str]: Input parameter stems emitted during encoding.
- to_pcvl_circuit(pcvl_module=None)
Convert the constructed circuit into a Perceval circuit.
- Args:
pcvl_module: Optional Perceval module. If
None, attempts to importperceval.- Returns:
A
pcvl.Circuitinstance mirroring the components tracked by this builder.- Raises:
ImportError: If
percevalis not installed and no module is provided.
- property trainable_parameter_prefixes: list[str]
Expose the unique set of trainable prefixes in insertion order.
- Returns:
List[str]: Trainable parameter stems discovered so far.
- class merlin.builder.circuit_builder.EntanglingBlock(targets='all', pattern='nearest_neighbor', depth=1, trainable=True, name_prefix=None)
Bases:
objectEntangling block description.
-
depth:
int= 1
- get_params()
Entangling blocks themselves carry no direct parameters.
- Return type:
dict[str,Any]
- Returns:
Dict[str, Any]: Always empty because entangling blocks are metadata-only.
-
name_prefix:
Optional[str] = None
-
pattern:
str= 'nearest_neighbor'
-
targets:
str|list[int] = 'all'
-
trainable:
bool= True
-
depth:
- class merlin.builder.circuit_builder.GenericInterferometer(start_mode, span, trainable=True, name_prefix=None, model='mzi', trainable_inner=None, trainable_outer=None)
Bases:
objectGeneric interferometer block spanning multiple modes.
- get_params()
Return placeholder names for every internal interferometer parameter.
- Return type:
dict[str,Any]
- Returns:
Dict[str, Any]: Mapping of generated parameter names to
Noneplaceholders.
-
model:
str= 'mzi'
-
name_prefix:
Optional[str] = None
-
span:
int
-
start_mode:
int
-
trainable:
bool= True
-
trainable_inner:
Optional[bool] = None
-
trainable_outer:
Optional[bool] = None
- class merlin.builder.circuit_builder.ModuleGroup(modes)
Bases:
objectHelper class for grouping modules.
- enum merlin.builder.circuit_builder.ParameterRole(value)
Bases:
EnumClear role definition for parameters.
Valid values are as follows:
- FIXED = <ParameterRole.FIXED: 'fixed'>
- INPUT = <ParameterRole.INPUT: 'input'>
- TRAINABLE = <ParameterRole.TRAINABLE: 'trainable'>
- class merlin.builder.circuit_builder.Rotation(target, role=ParameterRole.FIXED, value=0.0, axis='z', custom_name=None)
Bases:
objectRotation gate description.
The actual parameter name will be generated by the backend based on role.
-
axis:
str= 'z'
-
custom_name:
Optional[str] = None
- get_params()
Return declared parameter placeholders for the rotation.
Non-fixed rotations expose either their custom name or the automatically generated identifier so that downstream tooling can bind data or trainable tensors to the gate.
- Return type:
dict[str,Any]
- Returns:
Dict[str, Any]: Mapping from parameter name to placeholder value.
-
role:
ParameterRole= 'fixed'
-
target:
int
-
value:
float= 0.0
-
axis:
- class merlin.builder.circuit_builder.combinations(iterable, r)
Bases:
objectReturn successive r-length combinations of elements in the iterable.
combinations(range(4), 3) –> (0,1,2), (0,1,3), (0,2,3), (1,2,3)
The different components of the builder with their arguments and example of code
Below are the components available in the CircuitBuilder class:
add_rotations: - Adds one or multiple phase shifters across the specified modes. - Arguments:
modes (int | list[int] | ModuleGroup | None): Modes receiving the rotations. Defaults to all modes.
axis (str): Axis of rotation (default: “z”).
angle (float): Fixed rotation angle for non-trainable cases.
trainable (bool): Promote the rotations to trainable parameters.
name (str): Optional stem used for generated parameter names.
role (
ParameterRole): Explicitly set the parameter role.
add_angle_encoding: - Adds angle-based input encoding to the circuit. - Arguments:
modes (list[int]): Modes to target for encoding.
name (str): Prefix for generated input parameters.
scale (float): Scaling factor for angle mapping.
This will show as a rotation layer as data is encoded in phase shifters.
add_entangling_layer: - Adds an entangling layer spanning a range of modes (implemented with a generic interferometer). - Arguments:
modes (list[int]): Modes to span.
trainable (bool): Whether the entangling layer is trainable.
model (str): Choose “mzi” (default) or “bell” to select the interferometer template.
name (str): Optional prefix for parameter names.
trainable_inner (bool | None): Override to control whether the internal phases of the MZIs remain trainable.
trainable_outer (bool | None): Override to control the output phases at the end of the interferometer.
And to span it on different modes .. code-block:: python
builder = CircuitBuilder(n_modes=6) builder.add_entangling_layer(trainable=True, name=”U1”, modes = [0,3])
Switching to a Bell-style interferometer is as simple as:
add_superpositions: - Adds one or more beam splitters with optional depth. - Arguments:
targets (tuple[int, int] | list[tuple[int, int]]): Explicit mode pairs receiving beam splitters. When omitted, nearest neighbours across
modes(or all modes) are used.depth (int): Number of successive passes to apply.
theta (float): Mixing angle for fixed beam splitters.
phi (float): Relative phase for fixed beam splitters.
trainable (bool): Convenience flag marking both parameters trainable.
trainable_theta (bool): Whether the mixing angle is trainable.
trainable_phi (bool): Whether the relative phase is trainable.
modes (list[int] or ModuleGroup): Mode span used when
targetsis omitted.name (str): Optional prefix for generated parameter names.
- build:
Finalizes and returns the constructed circuit.