def set_covariance(self, other: "ExperimentalValue", cov: float = None): """Sets the covariance of this value with another value""" if not isinstance(other, ExperimentalValue): raise IllegalArgumentError("Cannot set covariance for non-QExPy defined values") if not isinstance(other, MeasuredValue): raise IllegalArgumentError("Only covariance between measurements is supported.") if cov is None and isinstance(other, RepeatedlyMeasuredValue): try: cov = utils.calculate_covariance(self.raw_data, other.raw_data) except ValueError: cov = None super().set_covariance(other, cov)
def set_covariance(var1: ExperimentalValue, var2: ExperimentalValue, cov: Real = None): """Sets the covariance between two measurements Args: var1, var2 (ExperimentalValue): the two values to set covariance between See Also: :py:func:`ExperimentalValue.set_covariance` Examples: >>> import qexpy as q >>> a = q.Measurement(5, 0.5) >>> b = q.Measurement(6, 0.3) >>> # The user can manually set the covariance between two values >>> q.set_covariance(a, b, 0.135) >>> q.get_covariance(a, b) 0.135 """ if any(not isinstance(var, ExperimentalValue) for var in [var1, var2]): raise IllegalArgumentError( "Cannot set covariance between non-QExPy defined variables") var1.set_covariance(var2, cov)
def __init__(self, data, error=None, **kwargs): if error is not None and not isinstance(error, Real): raise IllegalArgumentError("Invalid data type to record an uncertainty!") unit = kwargs.get("unit", "") name = kwargs.get("name", "") save = kwargs.get("save", True) super().__init__(unit, name, save=save) self._value, self._error = float(data), float(error) if error else 0.0
def __new__(cls, data, error=None, **kwargs): # pylint: disable=unused-argument if isinstance(data, Real): instance = super().__new__(cls) elif isinstance(data, ARRAY_TYPES): instance = super().__new__(RepeatedlyMeasuredValue) else: raise IllegalArgumentError("Invalid data type to record a measurement!") return instance
def set_correlation(self, other: "ExperimentalValue", corr: float = None): """Sets the correlation factor of this value with another value""" if not isinstance(other, ExperimentalValue): raise IllegalArgumentError("Cannot set correlation for non-QExPy defined values") if not isinstance(other, MeasuredValue): raise IllegalArgumentError("Only covariance between measurements is supported.") if self.std == 0 or other.std == 0: raise ArithmeticError("Cannot set correlation for values with 0 errors") if corr is None: raise IllegalArgumentError( "The correlation factor is not provided, and cannot be calculated!") # check that the result makes sense if corr > 1 or corr < -1: raise ValueError("The correlation factor: {} is non-physical".format(corr)) cov = corr * (self.std * other.std) # register the correlation between these measurements id_string = "_".join(sorted([str(self._id), str(other._id)])) correlation_record = Correlation(corr, cov) ExperimentalValue._correlations[id_string] = correlation_record
def set_correlation(var1: MeasuredValue, var2: MeasuredValue, corr: Real = None): """Sets the correlation factor between two MeasuredValue objects Args: var1, var2 (ExperimentalValue): the two values to set correlation between See Also: :py:func:`ExperimentalValue.set_correlation` """ if any(not isinstance(var, ExperimentalValue) for var in [var1, var2]): raise IllegalArgumentError( "Cannot set correlation between non-QExPy defined variables") var1.set_correlation(var2, corr)
def get_correlation(self, other: "ExperimentalValue") -> float: """Gets the correlation factor of this value with another value""" if not isinstance(other, ExperimentalValue): raise IllegalArgumentError("Can't find correlation for non-QExPy defined values") if not isinstance(other, MeasuredValue): return 0 # only covariance between measurements is supported. if self.std == 0 or other.std == 0: return 0 # constants don't correlate with anyone if self._id == other._id: return 1 # values have unit correlation with themselves id_string = "_".join(sorted([str(self._id), str(other._id)])) if id_string in ExperimentalValue._correlations: return ExperimentalValue._correlations[id_string].correlation return 0
def __wrap_data(data, error, unit, name) -> ExperimentalValueArray: """Wraps the data set into ExperimentalValueArray objects""" if isinstance(data, ExperimentalValueArray): if name: data.name = name if unit: data.unit = unit if error is not None: error_array = _get_error_array_helper(data, error, None) for x, e in zip(data, error_array): x.error = e return data if isinstance(data, ARRAY_TYPES): return ExperimentalValueArray(data, error, unit=unit, name=name) raise IllegalArgumentError("Cannot create XYDataSet with the given arguments.")
def validate_param_info(info, info_name: str, constraints: FitParamConstraints): """Validates the param information is valid and matches the fit model""" if not info: return # skip if there's nothing to check if not isinstance(info, (list, tuple)): raise IllegalArgumentError("\"{}\" has to be a list or a tuple.".format(info_name)) if constraints.var_len and len(info) < constraints.length: raise ValueError( "The length of \"{}\" ({}) doesn't match the number of parameters in the fit " "function ({} or higher)".format(info_name, len(info), constraints.length)) if not constraints.var_len and len(info) != constraints.length: raise ValueError( "The length of \"{}\" ({}) doesn't match the number of parameters in the fit " "function (expecting {})".format(info_name, len(info), constraints.length))
def get_correlation(var1: ExperimentalValue, var2: ExperimentalValue) -> float: """Finds the correlation between two ExperimentalValue instances Args: var1, var2 (ExperimentalValue): the two values to find correlation between Returns: The correlation factor between var1 and var2 See Also: :py:func:`ExperimentalValue.get_correlation` """ if any(not isinstance(var, ExperimentalValue) for var in [var1, var2]): raise IllegalArgumentError( "Cannot find correlation between non-QExPy defined variables") # As of now, only covariance between measurements are supported. if isinstance(var1, MeasuredValue) and isinstance(var2, MeasuredValue): return var1.get_correlation(var2) return 0
def derivative(self, other: ExperimentalValue) -> float: if not isinstance(other, ExperimentalValue): raise IllegalArgumentError( "You can only find derivative with respect to another ExperimentalValue") return 1 if self._id == other._id else op.differentiate(self._formula, other)
def derivative(self, other: "ExperimentalValue") -> float: if not isinstance(other, ExperimentalValue): raise IllegalArgumentError( "You can only find derivative with respect to another ExperimentalValue") # Derivative of a measurement with respect to anything other than itself is 0 return 1 if self._id == other._id else 0