Source code for qilisdk.noise.dephasing
# Copyright 2026 Qilimanjaro Quantum Tech
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import numpy as np
from loguru import logger
from qilisdk.core import QTensor
from .noise import Noise
from .protocols import AttachmentScope, HasAllowedScopes, SupportsStaticLindblad, SupportsTimeDerivedKraus
from .representations import KrausChannel, LindbladGenerator
from .utils import _identity, _sigma_z
[docs]
class Dephasing(Noise, SupportsTimeDerivedKraus, SupportsStaticLindblad, HasAllowedScopes):
"""Pure dephasing (Tphi) noise model for single qubits.
This model supports both Lindblad and time-derived Kraus forms, with
coherences decaying as exp(-t / Tphi).
"""
def __init__(self, *, t_phi: float) -> None:
"""Args:
t_phi (float): Dephasing time constant (must be > 0).
Raises:
ValueError: If t_phi is not positive.
"""
if t_phi <= 0:
raise ValueError("t_phi must be > 0.")
self._t_phi = float(t_phi)
@property
[docs]
def t_phi(self) -> float:
"""Return the dephasing time constant.
Returns:
The t_phi value.
"""
return self._t_phi
[docs]
def as_lindblad(self) -> LindbladGenerator:
logger.debug("[Dephasing] Building Lindblad representation with t_phi={}", self._t_phi)
gamma = 1.0 / self._t_phi
rate = gamma / 2.0
L = QTensor(_sigma_z())
return LindbladGenerator(jump_operators=[L], rates=[rate])
[docs]
def as_kraus_from_duration(self, *, duration: float) -> KrausChannel:
if duration < 0:
raise ValueError("duration must be >= 0.")
logger.debug("[Dephasing] Building Kraus representation from duration {} with t_phi={}", duration, self._t_phi)
gamma = float(np.exp(-duration / self._t_phi))
K0 = np.sqrt((1.0 + gamma) / 2.0) * _identity()
K1 = np.sqrt((1.0 - gamma) / 2.0) * _sigma_z()
return KrausChannel([QTensor(K0), QTensor(K1)])
@classmethod
[docs]
def allowed_scopes(cls) -> frozenset[AttachmentScope]:
return frozenset({AttachmentScope.GLOBAL, AttachmentScope.PER_QUBIT})
def __repr__(self) -> str:
return f"{type(self).__qualname__}(t_phi={self._t_phi})"