Skip to content

Commit

Permalink
Remove deprecated noise arguments (#674)
Browse files Browse the repository at this point in the history
* Remove deprecated noise arguments

* Fix UT

* Fix formatting

* Deleting simplefilters
  • Loading branch information
HGSilveri authored Apr 22, 2024
1 parent 7df66e3 commit 188d21d
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 163 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/psf/black
rev: 23.10.1
rev: 24.4.0
hooks:
- id: black-jupyter

Expand Down
48 changes: 1 addition & 47 deletions pulser-core/pulser/backend/noise_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
"""Defines a noise model class for emulator backends."""
from __future__ import annotations

import warnings
from dataclasses import dataclass, field, fields
from typing import Any, Literal, get_args
from typing import Literal, get_args

import numpy as np

Expand Down Expand Up @@ -69,16 +68,10 @@ class NoiseModel:
amp_sigma: Dictates the fluctuations in amplitude as a standard
deviation of a normal distribution centered in 1.
dephasing_rate: The rate of a dephasing error occuring (in rad/µs).
dephasing_prob: (Deprecated) The rate of a dephasing error occuring
(in rad/µs). Use `dephasing_rate` instead.
depolarizing_rate: The rate (in rad/µs) at which a depolarizing
error occurs.
depolarizing_prob: (Deprecated) The rate (in rad/µs) at which a
depolarizing error occurs. Use `depolarizing_rate` instead.
eff_noise_rates: The rate associated to each effective noise operator
(in rad/µs).
eff_noise_probs: (Deprecated) The rate associated to each effective
noise operator (in rad/µs). Use `eff_noise_rate` instead.
eff_noise_opers: The operators for the effective noise model.
"""

Expand All @@ -95,44 +88,8 @@ class NoiseModel:
depolarizing_rate: float = 0.05
eff_noise_rates: list[float] = field(default_factory=list)
eff_noise_opers: list[np.ndarray] = field(default_factory=list)
dephasing_prob: float | None = None
depolarizing_prob: float | None = None
eff_noise_probs: list[float] = field(default_factory=list)

def __post_init__(self) -> None:
default_field_value = {
field.name: field.default for field in fields(self)
}
for noise in ["dephasing", "depolarizing", "eff_noise"]:
# Probability and rates should be the same
prob_name = f"{noise}_prob{'s' if noise=='eff_noise' else ''}"
rate_name = f"{noise}_rate{'s' if noise=='eff_noise' else ''}"
prob, rate = (getattr(self, prob_name), getattr(self, rate_name))
if len(prob) > 0 if noise == "eff_noise" else prob is not None:
warnings.warn(
f"{prob_name} is deprecated. Use {rate_name} instead.",
DeprecationWarning,
)
if prob != rate:
if (
len(rate) > 0
if noise == "eff_noise"
else rate != default_field_value[rate_name]
):
raise ValueError(
f"If both defined, `{rate_name}` and `{prob_name}`"
" must be equal."
)
warnings.warn(
f"Setting {rate_name} with the value from "
f"{prob_name}.",
UserWarning,
)
self._change_attribute(rate_name, prob)
self._change_attribute(prob_name, getattr(self, rate_name))
assert self.dephasing_prob == self.dephasing_rate
assert self.depolarizing_prob == self.depolarizing_rate
assert self.eff_noise_probs == self.eff_noise_rates
positive = {
"dephasing_rate",
"depolarizing_rate",
Expand Down Expand Up @@ -174,9 +131,6 @@ def __post_init__(self) -> None:
self._check_noise_types()
self._check_eff_noise()

def _change_attribute(self, attr_name: str, new_value: Any) -> None:
object.__setattr__(self, attr_name, new_value)

def _check_noise_types(self) -> None:
for noise_type in self.noise_types:
if noise_type not in get_args(NOISE_TYPES):
Expand Down
5 changes: 1 addition & 4 deletions pulser-simulation/pulser_simulation/qutip_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"""Defines the QutipBackend class."""
from __future__ import annotations

import warnings
from typing import Any

from pulser import Sequence
Expand Down Expand Up @@ -44,9 +43,7 @@ def __init__(
f"not {type(config)}."
)
self._config = config
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
simconfig = SimConfig.from_noise_model(self._config.noise_model)
simconfig = SimConfig.from_noise_model(self._config.noise_model)
self._sim_obj = QutipEmulator.from_sequence(
sequence,
sampling_rate=self._config.sampling_rate,
Expand Down
16 changes: 1 addition & 15 deletions pulser-simulation/pulser_simulation/simconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,6 @@ class SimConfig:
eff_noise_rates: list[float] = field(default_factory=list, repr=False)
eff_noise_opers: list[qutip.Qobj] = field(default_factory=list, repr=False)
solver_options: Optional[qutip.Options] = None
dephasing_prob: float | None = None
depolarizing_prob: float | None = None
eff_noise_probs: list[float] = field(default_factory=list, repr=False)

@classmethod
def from_noise_model(cls: Type[T], noise_model: NoiseModel) -> T:
Expand All @@ -135,9 +132,6 @@ def from_noise_model(cls: Type[T], noise_model: NoiseModel) -> T:
depolarizing_rate=noise_model.depolarizing_rate,
eff_noise_rates=noise_model.eff_noise_rates,
eff_noise_opers=list(map(qutip.Qobj, noise_model.eff_noise_opers)),
dephasing_prob=noise_model.dephasing_prob,
depolarizing_prob=noise_model.depolarizing_prob,
eff_noise_probs=noise_model.eff_noise_probs,
)

def to_noise_model(self) -> NoiseModel:
Expand All @@ -156,9 +150,6 @@ def to_noise_model(self) -> NoiseModel:
depolarizing_rate=self.depolarizing_rate,
eff_noise_rates=self.eff_noise_rates,
eff_noise_opers=[op.full() for op in self.eff_noise_opers],
dephasing_prob=self.dephasing_prob,
depolarizing_prob=self.depolarizing_prob,
eff_noise_probs=self.eff_noise_probs,
)

def __post_init__(self) -> None:
Expand All @@ -179,12 +170,7 @@ def __post_init__(self) -> None:
self._check_eff_noise_opers_type()

# Runs the noise model checks
noise_model = self.to_noise_model()
# Update rates and probs
for noise in ["dephasing", "depolarizing", "eff_noise"]:
for qty in ["prob", "rate"]:
attr = f"{noise}_{qty}{'s' if noise=='eff_noise' else ''}"
self._change_attribute(attr, getattr(noise_model, attr))
self.to_noise_model()

@property
def spam_dict(self) -> dict[str, float]:
Expand Down
33 changes: 8 additions & 25 deletions pulser-simulation/pulser_simulation/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,9 @@ def __init__(
"`sampling_rate` is too small, less than 4 data points."
)
# Sets the config as well as builds the hamiltonian
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
noise_model: NoiseModel = (
config.to_noise_model()
if config
else SimConfig().to_noise_model()
)
noise_model: NoiseModel = (
config.to_noise_model() if config else SimConfig().to_noise_model()
)
self._hamiltonian = Hamiltonian(
self.samples_obj,
self._register.qubits,
Expand Down Expand Up @@ -201,9 +197,7 @@ def basis(self) -> dict[str, Any]:
@property
def config(self) -> SimConfig:
"""The current configuration, as a SimConfig instance."""
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
return SimConfig.from_noise_model(self._hamiltonian.config)
return SimConfig.from_noise_model(self._hamiltonian.config)

def set_config(self, cfg: SimConfig) -> None:
"""Sets current config to cfg and updates simulation parameters.
Expand All @@ -223,9 +217,7 @@ def set_config(self, cfg: SimConfig) -> None:
" support simulation of noise types:"
f"{', '.join(not_supported)}."
)
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
self._hamiltonian.set_config(cfg.to_noise_model())
self._hamiltonian.set_config(cfg.to_noise_model())

def add_config(self, config: SimConfig) -> None:
"""Updates the current configuration with parameters of another one.
Expand All @@ -252,9 +244,7 @@ def add_config(self, config: SimConfig) -> None:
" support simulation of noise types: "
f"{', '.join(not_supported)}."
)
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
noise_model = config.to_noise_model()
noise_model = config.to_noise_model()
old_noise_set = set(self._hamiltonian.config.noise_types)
new_noise_set = old_noise_set.union(noise_model.noise_types)
diff_noise_set = new_noise_set - old_noise_set
Expand All @@ -272,32 +262,25 @@ def add_config(self, config: SimConfig) -> None:
param_dict["laser_waist"] = noise_model.laser_waist
param_dict["amp_sigma"] = noise_model.amp_sigma
if "dephasing" in diff_noise_set:
param_dict["dephasing_prob"] = noise_model.dephasing_prob
param_dict["dephasing_rate"] = noise_model.dephasing_rate
if "depolarizing" in diff_noise_set:
param_dict["depolarizing_prob"] = noise_model.depolarizing_prob
param_dict["depolarizing_rate"] = noise_model.depolarizing_rate
if "eff_noise" in diff_noise_set:
param_dict["eff_noise_opers"] = noise_model.eff_noise_opers
param_dict["eff_noise_rates"] = noise_model.eff_noise_rates
param_dict["eff_noise_probs"] = noise_model.eff_noise_probs
# update runs:
param_dict["runs"] = noise_model.runs
param_dict["samples_per_run"] = noise_model.samples_per_run
# set config with the new parameters:
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
self._hamiltonian.set_config(NoiseModel(**param_dict))
self._hamiltonian.set_config(NoiseModel(**param_dict))

def show_config(self, solver_options: bool = False) -> None:
"""Shows current configuration."""
print(self.config.__str__(solver_options))

def reset_config(self) -> None:
"""Resets configuration to default."""
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
self._hamiltonian.set_config(SimConfig().to_noise_model())
self._hamiltonian.set_config(SimConfig().to_noise_model())

@property
def initial_state(self) -> qutip.Qobj:
Expand Down
64 changes: 3 additions & 61 deletions tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,35 +111,9 @@ def test_init_strict_pos(self, param):
[
"dephasing_rate",
"depolarizing_rate",
"dephasing_prob",
"depolarizing_prob",
],
)
def test_init_rate_like(self, param, value):
def create_noise_model(param, value):
if "prob" in param:
if value > 0:
with pytest.raises(
ValueError, match=f"{param}` must be equal."
):
with pytest.warns(
DeprecationWarning,
match=f"{param} is deprecated.",
):
NoiseModel(
**{
param: value,
"dephasing_rate": value * 10,
"depolarizing_rate": value * 10,
}
)
with pytest.warns(
(UserWarning, DeprecationWarning),
match=f"{param}",
):
return NoiseModel(**{param: value})
return NoiseModel(**{param: value})

if value < 0:
param_mess = (
"depolarizing_rate"
Expand All @@ -151,9 +125,9 @@ def create_noise_model(param, value):
match=f"'{param_mess}' must be None or greater "
f"than or equal to zero, not {value}.",
):
create_noise_model(param, value)
NoiseModel(**{param: value})
else:
noise_model = create_noise_model(param, value)
noise_model = NoiseModel(**{param: value})
if "depolarizing" in param:
assert noise_model.depolarizing_rate == value
elif "dephasing" in param:
Expand Down Expand Up @@ -187,7 +161,7 @@ def matrices(self):
matrices["I3"] = np.eye(3)
return matrices

def test_eff_noise_probs(self, matrices):
def test_eff_noise_rates(self, matrices):
with pytest.raises(
ValueError, match="The provided rates must be greater than 0."
):
Expand All @@ -196,38 +170,6 @@ def test_eff_noise_probs(self, matrices):
eff_noise_opers=[matrices["I"], matrices["X"]],
eff_noise_rates=[-1.0, 0.5],
)
with pytest.warns(
(UserWarning, DeprecationWarning), match="eff_noise_probs"
):
NoiseModel(
noise_types=("eff_noise",),
eff_noise_opers=[matrices["I"], matrices["X"]],
eff_noise_probs=[1.2, 0.5],
)

with pytest.warns(
DeprecationWarning, match="eff_noise_probs is deprecated."
):
NoiseModel(
noise_types=("eff_noise",),
eff_noise_opers=[matrices["I"], matrices["X"]],
eff_noise_rates=[1.2, 0.5],
eff_noise_probs=[1.2, 0.5],
)

with pytest.raises(
ValueError,
match="If both defined, `eff_noise_rates` and `eff_noise_probs`",
):
with pytest.warns(
DeprecationWarning, match="eff_noise_probs is deprecated."
):
NoiseModel(
noise_types=("eff_noise",),
eff_noise_opers=[matrices["I"], matrices["X"]],
eff_noise_probs=[1.4, 0.5],
eff_noise_rates=[1.2, 0.5],
)

def test_eff_noise_opers(self, matrices):
with pytest.raises(ValueError, match="The operators list length"):
Expand Down
10 changes: 4 additions & 6 deletions tests/test_simconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ def test_init():
)
config = SimConfig(noise="depolarizing")
assert config.temperature == 5e-5
with pytest.warns(DeprecationWarning, match="is deprecated"):
assert config.to_noise_model().temperature == 50
assert config.to_noise_model().temperature == 50
str_config = config.__str__(True)
assert "depolarizing" in str_config
config = SimConfig(
Expand Down Expand Up @@ -122,7 +121,6 @@ def test_from_noise_model():
p_false_pos=0.1,
state_prep_error=0.05,
)
with pytest.warns(DeprecationWarning, match="is deprecated"):
assert SimConfig.from_noise_model(noise_model) == SimConfig(
noise="SPAM", epsilon=0.1, epsilon_prime=0.4, eta=0.05
)
assert SimConfig.from_noise_model(noise_model) == SimConfig(
noise="SPAM", epsilon=0.1, epsilon_prime=0.4, eta=0.05
)
7 changes: 3 additions & 4 deletions tests/test_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,10 +1016,9 @@ def test_noisy_xy(matrices, masked_qubit, noise, result, n_collapse_ops):
with pytest.raises(
NotImplementedError, match="mode 'XY' does not support simulation of"
):
with pytest.warns(DeprecationWarning, match="is deprecated"):
sim._hamiltonian.set_config(
SimConfig(("SPAM", "doppler")).to_noise_model()
)
sim._hamiltonian.set_config(
SimConfig(("SPAM", "doppler")).to_noise_model()
)
with pytest.raises(
NotImplementedError, match="simulation of noise types: amplitude"
):
Expand Down

0 comments on commit 188d21d

Please sign in to comment.