Skip to content

Constructors

This module implements the constructor class.

build_qnn_from_configs(register, observable_config, fm_config=FeatureMapConfig(), ansatz_config=AnsatzConfig(), backend=BackendName.PYQTORCH, diff_mode=DiffMode.AD, measurement=None, noise=None, configuration=None, input_diff_mode=InputDiffMode.AD)

Build a QNN model.

PARAMETER DESCRIPTION
register

Number of qubits or a register object.

TYPE: int | Register

observable_config

Observable configuration(s).

TYPE: ObservableConfig | list[ObservableConfig]

fm_config

Feature map configuration.

TYPE: FeatureMapConfig DEFAULT: FeatureMapConfig()

ansatz_config

Ansatz configuration.

TYPE: AnsatzConfig DEFAULT: AnsatzConfig()

backend

The chosen quantum backend.

TYPE: BackendName DEFAULT: PYQTORCH

diff_mode

The differentiation engine to use. Choices are 'gpsr' or 'ad'.

TYPE: DiffMode DEFAULT: AD

measurement

Optional measurement protocol. If None, use exact expectation value with a statevector simulator.

TYPE: Measurements DEFAULT: None

noise

A noise model to use.

TYPE: Noise DEFAULT: None

configuration

Optional backend configuration.

TYPE: BackendConfiguration | dict DEFAULT: None

input_diff_mode

The differentiation mode for the input tensor.

TYPE: InputDiffMode DEFAULT: AD

RETURNS DESCRIPTION
QNN

A QNN model.

TYPE: QNN

Source code in qadence_model/models/qnn_constructors.py
def build_qnn_from_configs(
    register: int | Register,
    observable_config: ObservableConfig | list[ObservableConfig],
    fm_config: FeatureMapConfig = FeatureMapConfig(),
    ansatz_config: AnsatzConfig = AnsatzConfig(),
    backend: BackendName = BackendName.PYQTORCH,
    diff_mode: DiffMode = DiffMode.AD,
    measurement: Measurements | None = None,
    noise: NoiseHandler | None = None,
    configuration: BackendConfiguration | dict | None = None,
    input_diff_mode: InputDiffMode | str = InputDiffMode.AD,
) -> QNN:
    """
    Build a QNN model.

    Args:
        register (int | Register): Number of qubits or a register object.
        observable_config (ObservableConfig | list[ObservableConfig]): Observable configuration(s).
        fm_config (FeatureMapConfig): Feature map configuration.
        ansatz_config (AnsatzConfig): Ansatz configuration.
        backend (BackendName): The chosen quantum backend.
        diff_mode (DiffMode): The differentiation engine to use. Choices are
            'gpsr' or 'ad'.
        measurement (Measurements): Optional measurement protocol. If None,
            use exact expectation value with a statevector simulator.
        noise (Noise): A noise model to use.
        configuration (BackendConfiguration | dict): Optional backend configuration.
        input_diff_mode (InputDiffMode): The differentiation mode for the input tensor.

    Returns:
        QNN: A QNN model.
    """
    blocks: list[AbstractBlock] = []
    inputs: list[Basic | str] | None = None

    if fm_config.num_features > 0:
        fm_blocks = create_fm_blocks(register=register, config=fm_config)
        full_fm = _interleave_ansatz_in_fm(
            register=register,
            fm_blocks=fm_blocks,
            ansatz_config=ansatz_config,
        )
        if isinstance(fm_config.tag, str):
            tag(full_fm, fm_config.tag)
        inputs = fm_config.inputs
        blocks.append(full_fm)

    ansatz = create_ansatz(register=register, config=ansatz_config)
    if isinstance(ansatz_config.tag, str):
        tag(ansatz, ansatz_config.tag)
    blocks.append(ansatz)

    circ = QuantumCircuit(register, *blocks)

    observable: AbstractBlock | list[AbstractBlock] = (
        [create_observable(register=register, config=cfg) for cfg in observable_config]
        if isinstance(observable_config, list)
        else create_observable(register=register, config=observable_config)
    )

    ufa = QNN(
        circ,
        observable,
        inputs=inputs,
        backend=backend,
        diff_mode=diff_mode,
        measurement=measurement,
        noise=noise,
        configuration=configuration,
        input_diff_mode=input_diff_mode,
    )

    return ufa

create_ansatz(register, config)

Create the ansatz based on the configuration.

PARAMETER DESCRIPTION
register

Number of qubits or a register object.

TYPE: int | Register

config

Configuration for the ansatz.

TYPE: AnsatzConfig

RETURNS DESCRIPTION
AbstractBlock

The ansatz block.

TYPE: AbstractBlock

RAISES DESCRIPTION
NotImplementedError

If the ansatz type is not implemented.

Source code in qadence_model/models/qnn_constructors.py
def create_ansatz(
    register: int | Register,
    config: AnsatzConfig,
) -> AbstractBlock:
    """
    Create the ansatz based on the configuration.

    Args:
        register (int | Register): Number of qubits or a register object.
        config (AnsatzConfig): Configuration for the ansatz.

    Returns:
        AbstractBlock: The ansatz block.

    Raises:
        NotImplementedError: If the ansatz type is not implemented.
    """
    num_qubits = register if isinstance(register, int) else register.n_qubits

    if config.ansatz_type == AnsatzType.IIA:
        return _create_iia(num_qubits=num_qubits, config=config)
    elif config.ansatz_type == AnsatzType.HEA:
        return _create_hea(register=register, config=config)
    elif config.ansatz_type == AnsatzType.ALA:
        return _create_ala(num_qubits=num_qubits, config=config)
    else:
        raise NotImplementedError(
            f"Ansatz of type {config.ansatz_type} not implemented yet. Only `AnsatzType.HEA` and\
                `AnsatzType.IIA` available."
        )

create_fm_blocks(register, config)

Create a list of feature map blocks based on the given configuration.

In case of series encoding or even parallel encoding with data reuploads, the outputs is a list of blocks that still need to be interleaved with non commuting blocks.

PARAMETER DESCRIPTION
register

The number of qubits or the register.

TYPE: int | Register

config

The configuration for the feature map.

TYPE: FeatureMapConfig

RETURNS DESCRIPTION
list[AbstractBlock]

list[AbstractBlock]: A list of feature map blocks.

RAISES DESCRIPTION
ValueError

If the feature map strategy is not Strategy.DIGITAL, Strategy.ANALOG or Strategy.RYDBERG.

Source code in qadence_model/models/qnn_constructors.py
def create_fm_blocks(
    register: int | Register,
    config: FeatureMapConfig,
) -> list[AbstractBlock]:
    """
    Create a list of feature map blocks based on the given configuration.

    In case of series encoding or even parallel encoding with data reuploads,
    the outputs is a list of blocks that still need to be interleaved with non
    commuting blocks.

    Args:
        register (int | Register): The number of qubits or the register.
        config (FeatureMapConfig): The configuration for the feature map.

    Returns:
        list[AbstractBlock]: A list of feature map blocks.

    Raises:
        ValueError: If the feature map strategy is not `Strategy.DIGITAL`, `Strategy.ANALOG` or
            `Strategy.RYDBERG`.
    """
    if config.feature_map_strategy == Strategy.DIGITAL:
        return _create_digital_fm(register=register, config=config)
    elif config.feature_map_strategy == Strategy.ANALOG:
        return _create_analog_fm(register=register, config=config)
    elif config.feature_map_strategy == Strategy.RYDBERG:
        return _create_rydberg_fm(register=register, config=config)
    else:
        raise NotImplementedError(
            f"Feature map not implemented for strategy {config.feature_map_strategy}. \
            Only `Strategy.DIGITAL`, `Strategy.ANALOG` or `Strategy.RYDBERG` allowed."
        )

create_observable(register, config)

Create an observable block.

PARAMETER DESCRIPTION
register

Number of qubits or a register object.

TYPE: int | Register

config

Observable configuration.

TYPE: ObservableConfig

RETURNS DESCRIPTION
AbstractBlock

The observable block.

TYPE: AbstractBlock

Source code in qadence_model/models/qnn_constructors.py
def create_observable(
    register: int | Register,
    config: ObservableConfig,
) -> AbstractBlock:
    """
    Create an observable block.

    Args:
        register (int | Register): Number of qubits or a register object.
        config (ObservableConfig): Observable configuration.

    Returns:
        AbstractBlock: The observable block.
    """
    shifting_term: AbstractBlock = config.shift * _global_identity(register)  # type: ignore[operator]
    detuning_hamiltonian: AbstractBlock = config.scale * hamiltonian_factory(  # type: ignore[operator]
        register=register,
        interaction=config.interaction,
        detuning=config.detuning,
    )
    obs: AbstractBlock = add(shifting_term, detuning_hamiltonian)

    if isinstance(config.tag, str):
        tag(obs, config.tag)

    return obs