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)
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')
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)
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')
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')
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 )
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 )
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
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 )
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
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}')
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)
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)
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
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