From 241c7c98f644f93abd1031d510494a5b6b8b5bff Mon Sep 17 00:00:00 2001 From: HGSilveri Date: Wed, 24 Apr 2024 17:24:59 +0200 Subject: [PATCH 1/2] Add hyperfine dephasing rate to NoiseModel --- pulser-core/pulser/backend/noise_model.py | 11 ++++++++--- pulser-simulation/pulser_simulation/hamiltonian.py | 8 ++++++-- pulser-simulation/pulser_simulation/simconfig.py | 8 +++++++- pulser-simulation/pulser_simulation/simulation.py | 3 +++ tests/test_backend.py | 8 ++------ tests/test_simulation.py | 1 + 6 files changed, 27 insertions(+), 12 deletions(-) diff --git a/pulser-core/pulser/backend/noise_model.py b/pulser-core/pulser/backend/noise_model.py index 6d7aa884..f8ba5e11 100644 --- a/pulser-core/pulser/backend/noise_model.py +++ b/pulser-core/pulser/backend/noise_model.py @@ -48,7 +48,7 @@ class NoiseModel: characterized experimentally by the T1 time. - "dephasing": Random phase (Z) flip (parametrized by `dephasing_rate`), commonly characterized experimentally - by the T2 time. + by the T2* time. - "depolarizing": Quantum noise where the state is turned into a mixed state I/2 with rate `depolarizing_rate`. While it does not describe a physical phenomenon, it is a @@ -81,8 +81,11 @@ class NoiseModel: deviation of a normal distribution centered in 1. relaxation_rate: The rate of relaxation from the Rydberg to the ground state (in 1/µs). Corresponds to 1/T1. - dephasing_rate: The rate of a dephasing error occuring (in 1/µs). - Corresponds to 1/T2. + dephasing_rate: The rate of a dephasing occuring (in 1/µs) when a + Rydberg state is involved in the superposition. Corresponds + to 1/T2*. + hyperfine_dephasing_rate: The rate of dephasing occuring (in 1/µs) + between hyperfine ground states. depolarizing_rate: The rate (in 1/µs) at which a depolarizing error occurs. eff_noise_rates: The rate associated to each effective noise operator @@ -101,6 +104,7 @@ class NoiseModel: amp_sigma: float = 5e-2 relaxation_rate: float = 0.01 dephasing_rate: float = 0.05 + hyperfine_dephasing_rate: float = 1e-3 depolarizing_rate: float = 0.05 eff_noise_rates: list[float] = field(default_factory=list) eff_noise_opers: list[np.ndarray] = field(default_factory=list) @@ -108,6 +112,7 @@ class NoiseModel: def __post_init__(self) -> None: positive = { "dephasing_rate", + "hyperfine_dephasing_rate", "relaxation_rate", "depolarizing_rate", } diff --git a/pulser-simulation/pulser_simulation/hamiltonian.py b/pulser-simulation/pulser_simulation/hamiltonian.py index 0c0d2ed1..c0ea4cb0 100644 --- a/pulser-simulation/pulser_simulation/hamiltonian.py +++ b/pulser-simulation/pulser_simulation/hamiltonian.py @@ -116,8 +116,12 @@ def basis_check(noise_type: str) -> None: local_collapse_ops = [] if "dephasing" in config.noise_types: basis_check("dephasing") - coeff = np.sqrt(config.dephasing_rate / 2) - local_collapse_ops.append(coeff * qutip.sigmaz()) + rate = ( + config.hyperfine_dephasing_rate + if self.basis_name == "digital" + else config.dephasing_rate + ) + local_collapse_ops.append(np.sqrt(rate / 2) * qutip.sigmaz()) if "relaxation" in config.noise_types: coeff = np.sqrt(config.relaxation_rate) diff --git a/pulser-simulation/pulser_simulation/simconfig.py b/pulser-simulation/pulser_simulation/simconfig.py index 7e246ac1..22abf07a 100644 --- a/pulser-simulation/pulser_simulation/simconfig.py +++ b/pulser-simulation/pulser_simulation/simconfig.py @@ -110,6 +110,7 @@ class SimConfig: epsilon_prime: float = 0.05 relaxation_rate: float = 0.01 dephasing_rate: float = 0.05 + hyperfine_dephasing_rate: float = 1e-3 depolarizing_rate: float = 0.05 eff_noise_rates: list[float] = field(default_factory=list, repr=False) eff_noise_opers: list[qutip.Qobj] = field(default_factory=list, repr=False) @@ -129,6 +130,7 @@ def from_noise_model(cls: Type[T], noise_model: NoiseModel) -> T: epsilon=noise_model.p_false_pos, epsilon_prime=noise_model.p_false_neg, dephasing_rate=noise_model.dephasing_rate, + hyperfine_dephasing_rate=noise_model.hyperfine_dephasing_rate, relaxation_rate=noise_model.relaxation_rate, depolarizing_rate=noise_model.depolarizing_rate, eff_noise_rates=noise_model.eff_noise_rates, @@ -148,6 +150,7 @@ def to_noise_model(self) -> NoiseModel: laser_waist=self.laser_waist, amp_sigma=self.amp_sigma, dephasing_rate=self.dephasing_rate, + hyperfine_dephasing_rate=self.hyperfine_dephasing_rate, relaxation_rate=self.relaxation_rate, depolarizing_rate=self.depolarizing_rate, eff_noise_rates=self.eff_noise_rates, @@ -214,7 +217,10 @@ def __str__(self, solver_options: bool = False) -> str: if "relaxation" in self.noise: lines.append(f"Relaxation rate: {self.relaxation_rate}") if "dephasing" in self.noise: - lines.append(f"Dephasing rate: {self.dephasing_rate}") + lines.append( + f"Dephasing rate: {self.dephasing_rate} (Rydberg), " + f"{self.hyperfine_dephasing_rate} (Hyperfine)" + ) if "depolarizing" in self.noise: lines.append(f"Depolarizing rate: {self.depolarizing_rate}") if solver_options: diff --git a/pulser-simulation/pulser_simulation/simulation.py b/pulser-simulation/pulser_simulation/simulation.py index a88ea458..827acc97 100644 --- a/pulser-simulation/pulser_simulation/simulation.py +++ b/pulser-simulation/pulser_simulation/simulation.py @@ -263,6 +263,9 @@ def add_config(self, config: SimConfig) -> None: param_dict["amp_sigma"] = noise_model.amp_sigma if "dephasing" in diff_noise_set: param_dict["dephasing_rate"] = noise_model.dephasing_rate + param_dict["hyperfine_dephasing_rate"] = ( + noise_model.hyperfine_dephasing_rate + ) if "relaxation" in diff_noise_set: param_dict["relaxation_rate"] = noise_model.relaxation_rate if "depolarizing" in diff_noise_set: diff --git a/tests/test_backend.py b/tests/test_backend.py index 69bc32e1..a7da4663 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -110,6 +110,7 @@ def test_init_strict_pos(self, param): "param", [ "dephasing_rate", + "hyperfine_dephasing_rate", "relaxation_rate", "depolarizing_rate", ], @@ -124,12 +125,7 @@ def test_init_rate_like(self, param, value): NoiseModel(**{param: value}) else: noise_model = NoiseModel(**{param: value}) - if "depolarizing" in param: - assert noise_model.depolarizing_rate == value - elif "dephasing" in param: - assert noise_model.dephasing_rate == value - elif "relaxation" in param: - assert noise_model.relaxation_rate == value + assert getattr(noise_model, param) == value @pytest.mark.parametrize("value", [-1e-9, 1.0001]) @pytest.mark.parametrize( diff --git a/tests/test_simulation.py b/tests/test_simulation.py index 10c2fdca..29bc0a62 100644 --- a/tests/test_simulation.py +++ b/tests/test_simulation.py @@ -838,6 +838,7 @@ def test_noises_digital(matrices, noise, result, n_collapse_ops, seq_digital): sampling_rate=0.01, config=SimConfig( noise=noise, + hyperfine_dephasing_rate=0.05, eff_noise_opers=[matrices["Z"]], eff_noise_rates=[0.025], ), From c66ce9cbbfdad74acaa4a0cad6ad152299a416ad Mon Sep 17 00:00:00 2001 From: HGSilveri Date: Thu, 25 Apr 2024 10:58:20 +0200 Subject: [PATCH 2/2] Update NoiseModel docstring --- pulser-core/pulser/backend/noise_model.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pulser-core/pulser/backend/noise_model.py b/pulser-core/pulser/backend/noise_model.py index f8ba5e11..dcccb3e6 100644 --- a/pulser-core/pulser/backend/noise_model.py +++ b/pulser-core/pulser/backend/noise_model.py @@ -81,11 +81,12 @@ class NoiseModel: deviation of a normal distribution centered in 1. relaxation_rate: The rate of relaxation from the Rydberg to the ground state (in 1/µs). Corresponds to 1/T1. - dephasing_rate: The rate of a dephasing occuring (in 1/µs) when a - Rydberg state is involved in the superposition. Corresponds - to 1/T2*. + dephasing_rate: The rate of a dephasing occuring (in 1/µs) in a + Rydberg state superpostion. Only used if a Rydberg state is + involved. Corresponds to 1/T2*. hyperfine_dephasing_rate: The rate of dephasing occuring (in 1/µs) - between hyperfine ground states. + between hyperfine ground states. Only used if the hyperfine + state is involved. depolarizing_rate: The rate (in 1/µs) at which a depolarizing error occurs. eff_noise_rates: The rate associated to each effective noise operator