Source code for quara.protocol.qtomography.qtomography

from abc import abstractmethod
from typing import List, Tuple

import numpy as np

from quara.objects.qoperation import QOperation
from quara.objects.state import State
from quara.objects.povm import Povm
from quara.objects.gate import Gate
from quara.objects.mprocess import MProcess
from quara.objects.qoperations import SetQOperations
from quara.qcircuit.experiment import Experiment


[docs]class QTomography: def __init__( self, experiment: Experiment, set_qoperations: SetQOperations, ): """initialize quantum tomography class. To inherit from this class, set the following instance variables in the constructor of the subclass. - ``_num_variables``: sum of the number of all variables. Parameters ---------- experiment : Experiment Experiment class used in quantum tomography, which is supposed to have tester objects. set_qoperations : SetQOperations SetQOperations class used in quantum tomography, which is supposed to have conditions of true object. """ self._experiment = experiment self._num_schedules = len(self._experiment.schedules) self._set_qoperations = set_qoperations # validate ElementalSystem of Experiment for state in self._experiment.states: if ( not state is None and not state.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of Experiment must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(state)} is not so." ) # whether entries of vec of State are real numbers if not state is None and state.vec.dtype != np.float64: raise ValueError( f"entries of vec of State must be real numbers. dtype of vec is {state.vec.dtype}" ) for gate in self._experiment.gates: if ( not gate is None and not gate.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of Experiment must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(gate)} is not so." ) # whether entries of HS representation of Gate are real numbers if not gate is None and gate.hs.dtype != np.float64: raise ValueError( f"entries of HS representation of Gate must be real numbers. dtype of HS is {gate.hs.dtype}" ) for povm in self._experiment.povms: if ( not povm is None and not povm.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of Experiment must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(povm)} is not so." ) # whether entries of vecs of Povm are real numbers if not povm is None: for vec in povm.vecs: if vec.dtype != np.float64: raise ValueError( f"entries of all vecs of Povm must be real numbers. some dtype of vecs are {vec.dtype}" ) for mprocess in self._experiment.mprocesses: if ( not mprocess is None and not mprocess.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of Experiment must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(mprocess)} is not so." ) # whether entries of vecs of Povm are real numbers if not mprocess is None: for hs in mprocess.hss: if hs.dtype != np.float64: raise ValueError( f"entries of all hss of MProcess must be real numbers. some dtype of vecs are {hs.dtype}" ) # validate ElementalSystem of SetQOperations for state in self._set_qoperations.states: if ( not state is None and not state.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of SetQOperations must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(state)} is not so." ) for gate in self._set_qoperations.gates: if ( not gate is None and not gate.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of SetQOperations must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(gate)} is not so." ) for povm in self._set_qoperations.povms: if ( not povm is None and not povm.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of SetQOperations must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(povm)} is not so." ) for mprocess in self._set_qoperations.mprocesses: if ( not mprocess is None and not mprocess.composite_system.is_orthonormal_hermitian_0thprop_identity ): raise ValueError( f"all ElementalSystem of SetQOperations must be orthonormal, hermitian and 0th prop I. the ElementalSystem of {str(mprocess)} is not so." ) @property def experiment(self) -> Experiment: """returns Experiment class. Returns ------- Experiment Experiment class. """ return self._experiment @property def set_qoperations(self) -> SetQOperations: """returns SetQOperations class. Returns ------- SetQOperations SetQOperations class. """ return self._set_qoperations @property def num_schedules(self) -> int: """returns number of schedules. Returns ------- int number of schedules. """ return self._num_schedules @property def num_variables(self) -> int: """returns sum of the number of all variables. Returns ------- int sum of the number of all variables. """ return self._num_variables @property def states(self) -> List[State]: return self._experiment.states @property def povms(self) -> List[Povm]: return self._experiment.povms @property def gates(self) -> List[Gate]: return self._experiment.gates @property def mprocesses(self) -> List[MProcess]: return self._experiment.mprocesses @abstractmethod def _testers(self) -> QOperation: raise NotImplementedError() @property def testers(self) -> List[QOperation]: """returns tester objects. Returns ------- List[QOperation] tester objects. Raises ------ NotImplementedError this function does not be implemented in the subclass. """ return self._testers()
[docs] def reset_seed(self, seed: int = None) -> None: """reset new seed. if `seed` is None, reset by seed which Experiment already has. Parameters ---------- seed : int, optional new seed, None by default. """ if seed: self._experiment.reset_seed_data(seed) else: self._experiment.reset_seed_data(self._experiment.seed_data)
[docs] @abstractmethod def is_valid_experiment(self) -> bool: """returns whether the experiment is valid. this function must be implemented in the subclass. Returns ------- bool whether the experiment is valid. Raises ------ NotImplementedError this function does not be implemented in the subclass. """ raise NotImplementedError()
[docs] @abstractmethod def calc_prob_dist(self, qope: QOperation, schedule_index: int) -> List[float]: """calculates a probability distribution. this function must be implemented in the subclass. Parameters ---------- qope : QOperation QOperation to calculate a probability distribution. schedule_index : int schedule index. Returns ------- List[np.ndarray] a probability distribution. Raises ------ NotImplementedError this function does not be implemented in the subclass. """ raise NotImplementedError()
[docs] @abstractmethod def calc_prob_dists(self, qope: QOperation) -> List[List[float]]: """calculates probability distributions. this function must be implemented in the subclass. Parameters ---------- qope : QOperation QOperation to calculate probability distributions. Returns ------- List[List[np.ndarray]] probability distributions. Raises ------ NotImplementedError this function does not be implemented in the subclass. """ raise NotImplementedError()
[docs] @abstractmethod def generate_dataset(self, data_nums: List[int]) -> List[List[np.ndarray]]: """Run all the schedules to caluclate the probability distribution and generate random data. this function must be implemented in the subclass. Parameters ---------- data_nums : List[int] A list of the number of data to be generated in each schedule. This parameter should be a list of non-negative integers. Returns ------- List[List[np.ndarray]] Generated dataset. Raises ------ NotImplementedError this function does not be implemented in the subclass. """ raise NotImplementedError()
[docs] @abstractmethod def generate_empi_dists( self, qoperation: QOperation, num_sum: int ) -> List[Tuple[int, np.ndarray]]: """Generate empirical distributions using the data generated from probability distributions of all schedules. this function must be implemented in the subclass. Parameters ---------- qoperation : QOperation QOperation to use to generate the experience distributions. num_sum : int the number of data to use to generate the experience distributions for each schedule. Returns ------- List[Tuple[int, np.ndarray]] A list of tuples for the number of data and experience distributions for each schedules. Raises ------ NotImplementedError this function does not be implemented in the subclass. """ raise NotImplementedError()
[docs] @abstractmethod def func_prob_dist(self): raise NotImplementedError()
[docs] @abstractmethod def func_prob_dists(self): raise NotImplementedError()