Skip to content

Qutip

oqd_analog_emulator.qutip_backend

QutipBackend

Bases: BackendBase

Class representing the Qutip backend

Source code in oqd-analog-emulator/src/oqd_analog_emulator/qutip_backend.py
class QutipBackend(BackendBase):
    """
    Class representing the Qutip backend
    """

    def compile(self, task: Task):
        """
        Method for compiling program of task to a [`QutipExperiment`][oqd_analog_emulator.interface.QutipExperiment] and converting
        args of task to [`TaskArgsAnalog`][oqd_core.backend.task.TaskArgsAnalog].

        Args:
            task (Task): Quantum experiment to compile

        Returns:
            converted_circuit (QutipExperiment): QutipExperiment containing the compiled experiment for Qutip
            converted_args (TaskArgsQutip): args of analog layer are converted to args for QuTip.

        """
        # pass to canonicaliza the operators in the AnalogCircuit
        canonicalized_circuit = analog_operator_canonicalization(task.program)

        # This just canonicalizes the operators inside the TaskArgsAnalog
        # i.e. operators for Expectation
        canonicalized_args = analog_operator_canonicalization(task.args)

        # another pass which assigns the n_qreg and n_qmode of the
        # AnalogCircuit IR
        assigned_circuit = assign_analog_circuit_dim(canonicalized_circuit)

        # This just verifies that the operators in the args have the same
        # dimension as the operators in the AnalogCircuit
        verify_analog_args_dim(
            canonicalized_args,
            n_qreg=assigned_circuit.n_qreg,
            n_qmode=assigned_circuit.n_qmode,
        )

        # another pass which compiles AnalogCircuit to a QutipExperiment
        converted_circuit = compiler_analog_circuit_to_qutipIR(
            assigned_circuit, fock_cutoff=task.args.fock_cutoff
        )

        # This just converts the args so that the operators of the args are
        # converted to qutip objects
        converted_args = compiler_analog_args_to_qutipIR(canonicalized_args)

        return (
            converted_circuit,
            converted_args,
        )

    def run(
        self,
        task: Task,
    ):
        """
        Method to simulate an experiment using the QuTip backend

        Args:
            task (Optional[Task]): Run experiment from a [`Task`][oqd_core.backend.task.Task] object

        Returns:
            TaskResultAnalog object containing the simulation results.

        Note:
            only one of task or experiment must be provided.
        """

        # if experiment is None and args is not None:
        #     raise TypeError("args provided without QuTip experiment")
        # if experiment is not None and args is None:
        #     raise TypeError("QuTip experiment provided without args")
        #
        # if task is not None and experiment is not None:
        #     raise TypeError("Both task and experiment are given as inputs to run")
        # if experiment is None:
        #     experiment, args = self.compile(task=task)

        experiment, args = self.compile(task=task)

        return run_qutip_experiment(model=experiment, args=args)

compile(task: Task)

Method for compiling program of task to a QutipExperiment and converting args of task to [TaskArgsAnalog][oqd_core.backend.task.TaskArgsAnalog].

Parameters:

Name Type Description Default
task Task

Quantum experiment to compile

required

Returns:

Name Type Description
converted_circuit QutipExperiment

QutipExperiment containing the compiled experiment for Qutip

converted_args TaskArgsQutip

args of analog layer are converted to args for QuTip.

Source code in oqd-analog-emulator/src/oqd_analog_emulator/qutip_backend.py
def compile(self, task: Task):
    """
    Method for compiling program of task to a [`QutipExperiment`][oqd_analog_emulator.interface.QutipExperiment] and converting
    args of task to [`TaskArgsAnalog`][oqd_core.backend.task.TaskArgsAnalog].

    Args:
        task (Task): Quantum experiment to compile

    Returns:
        converted_circuit (QutipExperiment): QutipExperiment containing the compiled experiment for Qutip
        converted_args (TaskArgsQutip): args of analog layer are converted to args for QuTip.

    """
    # pass to canonicaliza the operators in the AnalogCircuit
    canonicalized_circuit = analog_operator_canonicalization(task.program)

    # This just canonicalizes the operators inside the TaskArgsAnalog
    # i.e. operators for Expectation
    canonicalized_args = analog_operator_canonicalization(task.args)

    # another pass which assigns the n_qreg and n_qmode of the
    # AnalogCircuit IR
    assigned_circuit = assign_analog_circuit_dim(canonicalized_circuit)

    # This just verifies that the operators in the args have the same
    # dimension as the operators in the AnalogCircuit
    verify_analog_args_dim(
        canonicalized_args,
        n_qreg=assigned_circuit.n_qreg,
        n_qmode=assigned_circuit.n_qmode,
    )

    # another pass which compiles AnalogCircuit to a QutipExperiment
    converted_circuit = compiler_analog_circuit_to_qutipIR(
        assigned_circuit, fock_cutoff=task.args.fock_cutoff
    )

    # This just converts the args so that the operators of the args are
    # converted to qutip objects
    converted_args = compiler_analog_args_to_qutipIR(canonicalized_args)

    return (
        converted_circuit,
        converted_args,
    )

run(task: Task)

Method to simulate an experiment using the QuTip backend

Parameters:

Name Type Description Default
task Optional[Task]

Run experiment from a [Task][oqd_core.backend.task.Task] object

required

Returns:

Type Description

TaskResultAnalog object containing the simulation results.

Note

only one of task or experiment must be provided.

Source code in oqd-analog-emulator/src/oqd_analog_emulator/qutip_backend.py
def run(
    self,
    task: Task,
):
    """
    Method to simulate an experiment using the QuTip backend

    Args:
        task (Optional[Task]): Run experiment from a [`Task`][oqd_core.backend.task.Task] object

    Returns:
        TaskResultAnalog object containing the simulation results.

    Note:
        only one of task or experiment must be provided.
    """

    # if experiment is None and args is not None:
    #     raise TypeError("args provided without QuTip experiment")
    # if experiment is not None and args is None:
    #     raise TypeError("QuTip experiment provided without args")
    #
    # if task is not None and experiment is not None:
    #     raise TypeError("Both task and experiment are given as inputs to run")
    # if experiment is None:
    #     experiment, args = self.compile(task=task)

    experiment, args = self.compile(task=task)

    return run_qutip_experiment(model=experiment, args=args)

oqd_analog_emulator.interface

TaskArgsQutip

Bases: VisitableBaseModel

Class representing args for QuTip

Attributes:

Name Type Description
layer str

the layer of the experiment (analog, atomic)

n_shots Union[int, None]

number of shots requested

fock_cutof int

fock_cutoff for QuTip simulation

dt float

timesteps for discrete time

metrics dict

metrics which should be computed for the experiment. This does not require any Measure instruction in the analog layer.

Source code in oqd-analog-emulator/src/oqd_analog_emulator/interface.py
class TaskArgsQutip(VisitableBaseModel):
    """
    Class representing args for QuTip

    Attributes:
        layer (str): the layer of the experiment (analog, atomic)
        n_shots (Union[int, None]): number of shots requested
        fock_cutof (int): fock_cutoff for QuTip simulation
        dt (float): timesteps for discrete time
        metrics (dict): metrics which should be computed for the experiment. This does not require any Measure instruction in the analog layer.
    """

    layer: Literal["analog"] = "analog"
    n_shots: Union[int, None] = 10
    fock_cutoff: int = 4
    dt: float = 0.1
    metrics: Dict[
        str, Union[EntanglementEntropyReyni, EntanglementEntropyVN, QutipExpectation]
    ] = {}

QutipOperation

Bases: VisitableBaseModel

Class representing a quantum operation in QuTip

Attributes:

Name Type Description
hamiltonian List[Qobj, str]

Hamiltonian to evolve by

duration float

Duration of the evolution

Source code in oqd-analog-emulator/src/oqd_analog_emulator/interface.py
class QutipOperation(VisitableBaseModel):
    """
    Class representing a quantum operation in QuTip

    Attributes:
        hamiltonian (List[qt.Qobj, str]): Hamiltonian to evolve by
        duration (float): Duration of the evolution
    """

    model_config = ConfigDict(arbitrary_types_allowed=True)
    hamiltonian: List[Tuple[qt.Qobj, MathExpr]]
    duration: float

QutipExperiment

Bases: VisitableBaseModel

Class representing a quantum experiment in qutip

Attributes:

Name Type Description
instructions List[QutipOperation]

List of quantum operations to apply

n_qreg NonNegativeInt

Number of qubit quantum registers

n_qmode NonNegativeInt

Number of modal quantum registers

args TaskArgsQutip

Arguments for the experiment

Source code in oqd-analog-emulator/src/oqd_analog_emulator/interface.py
class QutipExperiment(VisitableBaseModel):
    """
    Class representing a quantum experiment in qutip

    Attributes:
        instructions (List[QutipOperation]): List of quantum operations to apply
        n_qreg (NonNegativeInt): Number of qubit quantum registers
        n_qmode (NonNegativeInt): Number of modal quantum registers
        args (TaskArgsQutip): Arguments for the experiment
    """

    instructions: list[Union[QutipOperation, QutipMeasurement]]
    n_qreg: NonNegativeInt
    n_qmode: NonNegativeInt