Skip to content

Commit

Permalink
Add QutipEmulator class to perform simulations from samples instead o…
Browse files Browse the repository at this point in the history
…f sequences (pasqal-io#519)

* Draft Simulation

* Deleting zero atol

* Defining device in Simulation

* Finalizing QutipEmulator

* Take into account deprecation

* Solving read the docs issues

* Taking into account review comments

* Fixing typos

* Using generator for union of sets
  • Loading branch information
a-corni authored May 17, 2023
1 parent c869386 commit 1c8c828
Show file tree
Hide file tree
Showing 11 changed files with 460 additions and 174 deletions.
8 changes: 7 additions & 1 deletion pulser-core/pulser/sampler/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ def sample(
)
samples_list.append(samples)

optionals = {}
optionals: dict = dict()
if seq._slm_mask_targets and seq._slm_mask_time:
optionals["_slm_mask"] = _SlmMask(
seq._slm_mask_targets,
seq._slm_mask_time[1],
)
if seq._in_xy:
optionals["_magnetic_field"] = seq.magnetic_field
if hasattr(seq, "_measurement"):
# Has attribute measurement because sequence can't be parametrized
optionals["_measurement"] = seq._measurement

return SequenceSamples(
list(seq.declared_channels.keys()),
samples_list,
Expand Down
30 changes: 24 additions & 6 deletions pulser-core/pulser/sampler/samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ class SequenceSamples:
samples_list: list[ChannelSamples]
_ch_objs: dict[str, Channel]
_slm_mask: _SlmMask = field(default_factory=_SlmMask)
_magnetic_field: np.ndarray | None = None
_measurement: str | None = None

@property
def channel_samples(self) -> dict[str, ChannelSamples]:
Expand All @@ -303,6 +305,7 @@ def max_duration(self) -> int:
"""The maximum duration among the channel samples."""
return max(samples.duration for samples in self.samples_list)

@property
def used_bases(self) -> set[str]:
"""The bases with non-zero pulses."""
return {
Expand All @@ -313,6 +316,26 @@ def used_bases(self) -> set[str]:
if not ch_samples.is_empty()
}

@property
def _in_xy(self) -> bool:
"""Checks if the sequence is in XY mode."""
bases = {ch_obj.basis for ch_obj in self._ch_objs.values()}
in_xy = False
if "XY" in bases:
assert bases == {"XY"}
in_xy = True
return in_xy

def extend_duration(self, new_duration: int) -> SequenceSamples:
"""Extend the duration of each samples to a new duration."""
return replace(
self,
samples_list=[
sample.extend_duration(new_duration)
for sample in self.samples_list
],
)

def to_nested_dict(self, all_local: bool = False) -> dict:
"""Format in the nested dictionary form.
Expand All @@ -327,12 +350,7 @@ def to_nested_dict(self, all_local: bool = False) -> dict:
addressing ('Global' or 'Local'), the targeted basis
and, in the 'Local' case, the targeted qubit.
"""
bases = {ch_obj.basis for ch_obj in self._ch_objs.values()}
in_xy = False
if "XY" in bases:
assert bases == {"XY"}
in_xy = True
d = _prepare_dict(self.max_duration, in_xy=in_xy)
d = _prepare_dict(self.max_duration, in_xy=self._in_xy)
for chname, samples in zip(self.channels, self.samples_list):
cs = (
samples.extend_duration(self.max_duration)
Expand Down
2 changes: 1 addition & 1 deletion pulser-simulation/pulser_simulation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@

from pulser_simulation._version import __version__
from pulser_simulation.simconfig import SimConfig
from pulser_simulation.simulation import Simulation
from pulser_simulation.simulation import QutipEmulator, Simulation
Loading

0 comments on commit 1c8c828

Please sign in to comment.