Example #1
0
    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)
Example #2
0
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)
Example #3
0
 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
Example #4
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
Example #5
0
    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
Example #6
0
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)
Example #7
0
    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
Example #8
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.")
Example #9
0
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))
Example #10
0
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
Example #11
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)
Example #12
0
 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