Example #1
0
    def __rmul__(self, other):

        from probability.calculations.calculation_types import SampleCalculation
        from probability.calculations.calculation_types import \
            BinaryOperatorCalculation
        from probability.calculations.calculation_types.value_calculation import \
            ValueCalculation

        if isinstance(other, ProbabilityCalculationMixin):
            context = other.context
            input_1 = other
        else:
            context = CalculationContext()
            if is_scalar(other):
                input_1 = ValueCalculation(calc_input=other, context=context)
            elif is_rvs(other):
                input_1 = SampleCalculation(calc_input=other, context=context)
            elif isinstance(other, Series) or isinstance(other, DataFrame):
                return other * self
            else:
                raise TypeError(
                    'other must be type Rvs1dMixin, RvsNdMixin float, '
                    'Series or DataFrame')

        input_2 = SampleCalculation(calc_input=self, context=context)

        return BinaryOperatorCalculation(calc_input_1=input_1,
                                         calc_input_2=input_2,
                                         operator=MultiplyOperator,
                                         context=context)
Example #2
0
    def __ne__(self, other: Union['Poisson', int,
                                  float]) -> Union[bool, float]:

        if is_scalar(other):
            return 1 - self.pmf().at(other)
        else:
            return not self.__eq__(other)
    def __ge__(self, other: Union['RVS1dMixin', int, float]) -> float:

        if is_scalar(other):
            return 1 - self.__le__(other)
        elif isinstance(other, RVS1dMixin):
            return super(RVContinuous1dMixin, self).__ge__(other)
        else:
            raise TypeError('other must be of type int, float or Rvs1dMixin')
Example #4
0
    def __ne__(
            self, other: Union['NegativeBinomial', int,
                               float]) -> Union[bool, float]:

        if is_scalar(other):
            return 1 - self.pmf().at(other)
        else:
            return not self.__eq__(other)
Example #5
0
    def __gt__(self, other: Union['RVS1dMixin', int, float]) -> float:

        if is_scalar(other):
            return 1 - self.cdf().at(other)
        elif isinstance(other, RVS1dMixin):
            return super(RVDiscrete1dMixin, self).__gt__(other)
        else:
            raise TypeError('other must be of type int, float or Rvs1dMixin')
Example #6
0
    def __ge__(self, other: Union['RVS1dMixin', int, float]) -> float:

        if is_scalar(other):
            return (self.rvs(NUM_SAMPLES_COMPARISON) >= other).mean()
        elif isinstance(other, RVS1dMixin):
            return (self.rvs(NUM_SAMPLES_COMPARISON) >=
                    other.rvs(NUM_SAMPLES_COMPARISON)).mean()
        else:
            raise TypeError('other must be of type float or Rvs1dMixin')
Example #7
0
    def __eq__(self, other: Union['BetaBinomial', int, float]):

        if is_scalar(other):
            return self.pmf().at(other)
        else:
            return (
                self._n == other._n and
                abs(self._alpha - other._alpha) < 1e-10 and
                abs(self._beta - other._beta) < 1e-10
            )
Example #8
0
    def __eq__(self, other: Union['HyperGeometric', int, float]):

        if is_scalar(other):
            return self.pmf().at(other)
        else:
            return (
                self._N == other._N and
                self._K == other._K and
                self._n == other._n
            )
Example #9
0
    def output(
            self,
            num_samples: Optional[int] = NUM_SAMPLES_COMPARISON
    ) -> CalculationValue:
        """
        Calculate the sampled output of the Calculation if it does not already
        exist.

        :param num_samples: Number of samples to draw.
        """
        if self.context.has_object_named(self.name):
            return self.context[self.name]
        else:
            # get input 1
            if self.context.has_object_named(self.calc_input_1.name):
                input_value_1 = self.context[self.calc_input_1.name]
            else:
                input_value_1 = self.calc_input_1.output(
                    num_samples=num_samples)
                self.context[self.calc_input_1.name] = input_value_1
            # get input 2
            if self.context.has_object_named(self.calc_input_2.name):
                input_value_2 = self.context[self.calc_input_2.name]
            else:
                input_value_2 = self.calc_input_2.output(
                    num_samples=num_samples)
                self.context[self.calc_input_2.name] = input_value_2
            # calculate output
            value_1_calc = not (
                is_scalar(self.calc_input_1) or
                isinstance(self.calc_input_1, SimpleCalculation)
            )
            value_2_calc = not (
                is_scalar(self.calc_input_2) or
                isinstance(self.calc_input_2, SimpleCalculation)
            )
            result = self.operator.operate(
                value_1=input_value_1, value_2=input_value_2,
                value_1_calc=value_1_calc, value_2_calc=value_2_calc
            )
            self.context[self.name] = result
            return result
Example #10
0
    def __eq__(
            self, other: Union['Binomial', int, float]
    ) -> Union[bool, float]:

        if is_scalar(other):
            return self.pmf().at(other)
        else:
            return (
                self._n == other._n and
                abs(self._p - other._p) < 1e-10
            )
Example #11
0
    def __init__(self, prior: Union[float, Beta, AnyFloatMap, AnyBetaMap],
                 likelihood: Union[float, Beta, AnyFloatMap, AnyBetaMap]):
        """
        Create a new Bayes Rule object from:
          - the prior P(A)
          - the likelihood P(B|A)
          - the evidence P(B)

        :param prior: Single figure or Beta-distributed probability representing
                      the hypothesis.
        :param likelihood: Series with values of Dirichlet likelihoods.
        """
        if not (is_scalar(prior) or isinstance(prior, Beta)
                or is_any_numeric_map(prior) or is_any_beta_map(prior)):
            raise ValueError('wrong type for prior')
        if not (is_scalar(likelihood) or isinstance(likelihood, Beta) or
                is_any_numeric_map(likelihood) or is_any_beta_map(likelihood)):
            raise ValueError('wrong type for prior')

        self._prior: Union[float, Beta, AnyFloatMap, AnyBetaMap] = prior
        self._likelihood: Union[float, Beta, AnyFloatMap,
                                AnyBetaMap] = likelihood
Example #12
0
    def operate(cls, values: List[CalculationValue]) -> CalculationValue:
        """
        Execute the operation on a list of input values.

        :param values: The values to operate on.
        """
        if all([is_scalar(v) for v in values]):
            return cls.operator(values)
        elif all([isinstance(v, Series) for v in values]):
            data = concat(values, axis=1)
            return data.apply(cls.pandas_op_name, axis=1)
        else:
            types = [type(v) for v in values]
            raise TypeError(f'Unsupported types in values. {types}')
Example #13
0
    def __truediv__(self, other):
        """
        Multiply the Distribution by a float, distribution, Series or DataFrame.

        :param other: The divisor. N.B. if it is a Series or a DataFrame,
                      the context of each value will not be synced. Use
                      `sync_context` if syncing is needed.
        """
        from probability.calculations.calculation_types import SampleCalculation
        from probability.calculations.calculation_types import \
            BinaryOperatorCalculation
        from probability.calculations.calculation_types.value_calculation import \
            ValueCalculation

        if isinstance(other, ProbabilityCalculationMixin):
            context = other.context
            input_2 = other
        else:
            context = CalculationContext()
            if is_scalar(other):
                input_2 = ValueCalculation(calc_input=other, context=context)
            elif is_rvs(other):
                input_2 = SampleCalculation(calc_input=other, context=context)
            elif isinstance(other, Series):
                return Series(
                    {key: self / value
                     for key, value in other.iteritems()})
            elif isinstance(other, DataFrame):
                return DataFrame({
                    column: {
                        key: self / value
                        for key, value in other[column].iteritems()
                    }
                    for column in other.columns
                })
            else:
                raise TypeError(
                    'other must be type Rvs1dMixin, RvsNdMixin float, '
                    'Series or DataFrame')

        input_1 = SampleCalculation(calc_input=self, context=context)

        return BinaryOperatorCalculation(calc_input_1=input_1,
                                         calc_input_2=input_2,
                                         operator=DivideOperator,
                                         context=context)
def reverse_binary_operation(item_1, item_2, builtin_operator,
                             calc_operator_type):

    if isinstance(item_2, ProbabilityCalculationMixin):
        input_1 = item_2
        input_1.set_context(item_1.context)
    else:
        context = CalculationContext()
        if is_scalar(item_2):
            input_1 = ValueCalculation(calc_input=item_2, context=context)
        elif is_rvs(item_2):
            input_1 = SampleCalculation(calc_input=item_2, context=context)
        elif isinstance(item_2, Series):
            return Series({
                key: builtin_operator(value, item_1)
                for key, value in item_2.items()
            })
        elif isinstance(item_2, DataFrame):
            return DataFrame({
                column: {
                    key: builtin_operator(value, item_1)
                    for key, value in item_2[column].items()
                }
                for column in item_2.columns
            })
        else:
            raise TypeError(
                'item_2 must be type Rvs1dMixin, RvsNdMixin, int, float, '
                'Series or DataFrame')

    from \
        probability.calculations.calculation_types.binary_operator_calculation \
        import BinaryOperatorCalculation

    return BinaryOperatorCalculation(calc_input_1=input_1,
                                     calc_input_2=item_1,
                                     operator=calc_operator_type,
                                     context=item_1.context)
Example #15
0
    def __eq__(self, other: Union['NegativeBinomial', int, float]):

        if is_scalar(other):
            return self.pmf().at(other)
        else:
            return (self._r == other._r and abs(self._p - other._p) < 1e-10)
Example #16
0
    def __eq__(self, other: Union['Geometric', int, float]):

        if is_scalar(other):
            return self.pmf().at(other)
        else:
            return abs(self._p - other._p) < 1e-10
Example #17
0
    def __eq__(self, other: Union['Poisson', int, float]):

        if is_scalar(other):
            return self.pmf().at(other)
        else:
            return abs(self._lambda - other._lambda) < 1e-10