Source code for quara.protocol.qtomography.standard.loss_minimization_estimator

import time
from typing import List, Tuple

import numpy as np

from quara.loss_function.probability_based_loss_function import (
    ProbabilityBasedLossFunction,
    ProbabilityBasedLossFunctionOption,
)
from quara.minimization_algorithm.minimization_algorithm import (
    MinimizationAlgorithm,
    MinimizationAlgorithmOption,
)
from quara.protocol.qtomography.standard.standard_qtomography import StandardQTomography
from quara.protocol.qtomography.standard.standard_qtomography_estimator import (
    StandardQTomographyEstimator,
    StandardQTomographyEstimationResult,
)


[docs]class LossMinimizationEstimationResult(StandardQTomographyEstimationResult): def __init__( self, qtomography: StandardQTomography, data, estimated_var_sequence: List[np.ndarray], computation_times: List[float], ): super().__init__(qtomography, data, estimated_var_sequence, computation_times)
[docs]class LossMinimizationEstimator(StandardQTomographyEstimator): def __init__(self): super().__init__()
[docs] def calc_estimate( self, qtomography: StandardQTomography, empi_dists: List[Tuple[int, np.ndarray]], loss: ProbabilityBasedLossFunction, loss_option: ProbabilityBasedLossFunctionOption, algo: MinimizationAlgorithm, algo_option: MinimizationAlgorithmOption, is_computation_time_required: bool = False, ) -> StandardQTomographyEstimationResult: """calculates estimate variables. Notice: this function updates ``loss`` and ``algo`` properties. Parameters ---------- qtomography : StandardQTomography StandardQTomography to calculates estimate variables. empi_dists : List[Tuple[int, np.ndarray]] empirical distributions to calculates estimate variables. loss : ProbabilityBasedLossFunction ProbabilityBasedLossFunction to calculates estimate variables. loss_option : ProbabilityBasedLossFunctionOption ProbabilityBasedLossFunctionOption to calculates estimate variables. algo : MinimizationAlgorithm MinimizationAlgorithm to calculates estimate variables. algo_option : MinimizationAlgorithmOption MinimizationAlgorithmOption to calculates estimate variables. is_computation_time_required : bool, optional whether to include computation time in the return value or not, by default False. Returns ------- StandardQTomographyEstimationResult estimation result. Raises ------ ValueError loss.is_option_sufficient() returns False. ValueError algo.is_loss_sufficient() returns False. ValueError algo.is_option_sufficient() returns False. ValueError algo.is_loss_and_option_sufficient() returns False. """ result = self.calc_estimate_sequence( qtomography, [empi_dists], loss, loss_option, algo, algo_option, is_computation_time_required=is_computation_time_required, ) return result
[docs] def calc_estimate_sequence( self, qtomography: StandardQTomography, empi_dists_sequence: List[List[Tuple[int, np.ndarray]]], loss: ProbabilityBasedLossFunction, loss_option: ProbabilityBasedLossFunctionOption, algo: MinimizationAlgorithm, algo_option: MinimizationAlgorithmOption, is_computation_time_required: bool = False, ) -> StandardQTomographyEstimationResult: """calculates sequence of estimate variables. Notice: this function updates ``loss`` and ``algo`` properties. Parameters ---------- qtomography : StandardQTomography StandardQTomography to calculates estimate variables. empi_dists_sequence : List[List[Tuple[int, np.ndarray]]] sequence of empirical distributions to calculates estimate variables. loss : ProbabilityBasedLossFunction ProbabilityBasedLossFunction to calculates estimate variables. loss_option : ProbabilityBasedLossFunctionOption ProbabilityBasedLossFunctionOption to calculates estimate variables. algo : MinimizationAlgorithm MinimizationAlgorithm to calculates estimate variables. algo_option : MinimizationAlgorithmOption MinimizationAlgorithmOption to calculates estimate variables. is_computation_time_required : bool, optional whether to include computation time in the return value or not, by default False. Returns ------- StandardQTomographyEstimationResult estimation result. Raises ------ ValueError loss.is_option_sufficient() returns False. ValueError algo.is_loss_sufficient() returns False. ValueError algo.is_option_sufficient() returns False. ValueError algo.is_loss_and_option_sufficient() returns False. """ estimated_var_sequence = [] computation_times = [] if is_computation_time_required else None for empi_dists in empi_dists_sequence: if is_computation_time_required: start_time = time.time() # set loss settings loss.set_from_standard_qtomography_option_data( qtomography, loss_option, empi_dists, algo.is_gradient_required, algo.is_hessian_required, ) # set algorithm settings algo.set_from_option(algo_option) algo.set_constraint_from_standard_qt_and_option(qtomography, algo_option) algo.set_from_loss(loss) # validate if loss.is_option_sufficient() == False: raise ValueError( "loss.is_option_sufficient() must return True. But returns False" ) if algo.is_loss_sufficient() == False: raise ValueError( "algo.is_loss_sufficient() must return True. But returns False" ) if algo.is_option_sufficient() == False: raise ValueError( "algo.is_option_sufficient() must return True. But returns False" ) if algo.is_loss_and_option_sufficient() == False: raise ValueError( "algo.is_loss_and_option_sufficient() must return True. But returns False" ) if is_computation_time_required: prepare_time = time.time() - start_time # optimize algo_result = algo.optimize( loss, loss_option, algo_option, on_iteration_history=is_computation_time_required, ) # post-processing estimated_var_sequence.append(algo_result.value) if is_computation_time_required: computation_times.append(prepare_time + algo_result.computation_time) result = LossMinimizationEstimationResult( qtomography, empi_dists_sequence, estimated_var_sequence, computation_times ) return result