Source code for mqt.qudits.simulation.backends.misim
# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM
# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH
# All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Licensed under the MIT License
from __future__ import annotations
import operator
from functools import reduce
from typing import TYPE_CHECKING
import numpy as np
from typing_extensions import Unpack
from ..._qudits.misim import state_vector_simulation
from ..jobs import Job, JobResult
from ..noise_tools import NoiseModel
from .backendv2 import Backend
from .stochastic_sim import stochastic_simulation
if TYPE_CHECKING:
from numpy.typing import NDArray
from ...quantum_circuit import QuantumCircuit
from .. import MQTQuditProvider
[docs]
class MISim(Backend):
def __init__(
self,
provider: MQTQuditProvider,
name: str | None = None,
description: str | None = None,
**fields: Unpack[Backend.DefaultOptions],
) -> None:
super().__init__(provider, name=name, description=description, **fields)
def __noise_model(self) -> NoiseModel | None:
return self.noise_model
[docs]
def run(self, circuit: QuantumCircuit, **options: Unpack[Backend.DefaultOptions]) -> Job:
job = Job(self)
self._options.update(options)
self.noise_model = self._options.get("noise_model", None)
self.shots = self._options.get("shots", 50)
self.memory = self._options.get("memory", False)
self.full_state_memory = self._options.get("full_state_memory", False)
self.file_path = self._options.get("file_path", None)
self.file_name = self._options.get("file_name", None)
if self.noise_model is not None:
assert self.shots >= 50, "Number of shots should be above 50"
job.set_result(JobResult(state_vector=self.execute(circuit), counts=stochastic_simulation(self, circuit))) # type: ignore [arg-type]
else:
job.set_result(JobResult(state_vector=self.execute(circuit), counts=[]))
return job
[docs]
def execute(self, circuit: QuantumCircuit, noise_model: NoiseModel | None = None) -> NDArray[np.complex128]:
self.system_sizes = circuit.dimensions
self.circ_operations = circuit.instructions
if noise_model is None:
noise_model = NoiseModel()
result = state_vector_simulation(circuit, noise_model)
state = np.array(result)
state_size = reduce(operator.mul, self.system_sizes, 1)
# Reverse the dimensions of the circuit and reshape the state array
reversed_dimensions = list(reversed(circuit.dimensions))
state = state.reshape(reversed_dimensions)
# Reverse the order of the axes for the transpose operation
axes_order = list(reversed(list(range(len(circuit.dimensions)))))
# Transpose the state array
state = np.transpose(state, axes_order)
return state.reshape((1, state_size))