def test_Compound_Distribution(): X = Normal('X', 2, 4) N = NormalDistribution(X, 4) C = CompoundDistribution(N) assert C.is_Continuous assert C.set == Interval(-oo, oo) assert C.pdf(x, evaluate=True).simplify() == exp(-x**2/64 + x/16 - S(1)/16)/(8*sqrt(pi)) assert not isinstance(CompoundDistribution(NormalDistribution(2, 3)), CompoundDistribution) M = MultivariateNormalDistribution([1, 2], [[2, 1], [1, 2]]) raises(NotImplementedError, lambda: CompoundDistribution(M)) X = Beta('X', 2, 4) B = BernoulliDistribution(X, 1, 0) C = CompoundDistribution(B) assert C.is_Finite assert C.set == {0, 1} y = symbols('y', negative=False, integer=True) assert C.pdf(y, evaluate=True) == Piecewise((S(1)/(30*beta(2, 4)), Eq(y, 0)), (S(1)/(60*beta(2, 4)), Eq(y, 1)), (0, True)) k, t, z = symbols('k t z', positive=True, real=True) G = Gamma('G', k, t) X = PoissonDistribution(G) C = CompoundDistribution(X) assert C.is_Discrete assert C.set == S.Naturals0 assert C.pdf(z, evaluate=True).simplify() == t**z*(t + 1)**(-k - z)*gamma(k \ + z)/(gamma(k)*gamma(z + 1))
def doit(self, **hints): condition = self.args[0] given_condition = self._condition numsamples = hints.get('numsamples', False) for_rewrite = not hints.get('for_rewrite', False) if isinstance(condition, Not): return S.One - self.func(condition.args[0], given_condition, evaluate=for_rewrite).doit(**hints) if condition.has(RandomIndexedSymbol): return pspace(condition).probability(condition, given_condition, evaluate=for_rewrite) if isinstance(given_condition, RandomSymbol): condrv = random_symbols(condition) if len(condrv) == 1 and condrv[0] == given_condition: from sympy.stats.frv_types import BernoulliDistribution return BernoulliDistribution( self.func(condition).doit(**hints), 0, 1) if any([dependent(rv, given_condition) for rv in condrv]): return Probability(condition, given_condition) else: return Probability(condition).doit() if given_condition is not None and \ not isinstance(given_condition, (Relational, Boolean)): raise ValueError( "%s is not a relational or combination of relationals" % (given_condition)) if given_condition == False or condition is S.false: return S.Zero if not isinstance(condition, (Relational, Boolean)): raise ValueError( "%s is not a relational or combination of relationals" % (condition)) if condition is S.true: return S.One if numsamples: return sampling_P(condition, given_condition, numsamples=numsamples) if given_condition is not None: # If there is a condition # Recompute on new conditional expr return Probability(given(condition, given_condition)).doit() # Otherwise pass work off to the ProbabilitySpace if pspace(condition) == PSpace(): return Probability(condition, given_condition) result = pspace(condition).probability(condition) if hasattr(result, 'doit') and for_rewrite: return result.doit() else: return result
def test_issue_12237(): X = Normal('X', 0, 1) Y = Normal('Y', 0, 1) U = P(X > 0, X) V = P(Y < 0, X) W = P(X + Y > 0, X) assert W == P(X + Y > 0, X) assert U == BernoulliDistribution(S(1) / 2, S(0), S(1)) assert V == S(1) / 2
def test_issue_12237(): X = Normal('X', 0, 1) Y = Normal('Y', 0, 1) U = P(X > 0, X) V = P(Y < 0, X) W = P(X + Y > 0, X) assert W == P(X + Y > 0, X) assert U == BernoulliDistribution(S.Half, S.Zero, S.One) assert V == S.Half
def probability(self, condition, given_condition=None, evaluate=True, **kwargs): """ Computes probability. Parameters ========== condition: Relational Condition for which probability has to be computed. Must contain a RandomIndexedSymbol of the process. given_condition: Relational/And The given conditions under which computations should be done. Returns ======= Probability of the condition. """ new_condition, new_givencondition = self._rvindexed_subs( condition, given_condition) if isinstance(new_givencondition, RandomSymbol): condrv = random_symbols(new_condition) if len(condrv) == 1 and condrv[0] == new_givencondition: return BernoulliDistribution(self.probability(new_condition), 0, 1) if any([dependent(rv, new_givencondition) for rv in condrv]): return Probability(new_condition, new_givencondition) else: return self.probability(new_condition) if new_givencondition is not None and \ not isinstance(new_givencondition, (Relational, Boolean)): raise ValueError( "%s is not a relational or combination of relationals" % (new_givencondition)) if new_givencondition == False: return S.Zero if new_condition == True: return S.One if new_condition == False: return S.Zero if not isinstance(new_condition, (Relational, Boolean)): raise ValueError( "%s is not a relational or combination of relationals" % (new_condition)) if new_givencondition is not None: # If there is a condition # Recompute on new conditional expr return self.probability( given(new_condition, new_givencondition, **kwargs), **kwargs) return pspace(new_condition).probability(new_condition, **kwargs)
def __new__(cls, sym, p, success=1, failure=0): _value_check(p >= 0 and p <= 1, 'Value of p must be between 0 and 1.') p = _sympify(p) sym = _symbol_converter(sym) success = _sym_sympify(success) failure = _sym_sympify(failure) state_space = _set_converter([success, failure]) return Basic.__new__(cls, sym, state_space, BernoulliDistribution(p), p, success, failure)
def test_compound_pspace(): X = Normal('X', 2, 4) Y = Normal('Y', 3, 6) assert not isinstance(Y.pspace, CompoundPSpace) N = NormalDistribution(1, 2) D = PoissonDistribution(3) B = BernoulliDistribution(0.2, 1, 0) pspace1 = CompoundPSpace('N', N) pspace2 = CompoundPSpace('D', D) pspace3 = CompoundPSpace('B', B) assert not isinstance(pspace1, CompoundPSpace) assert not isinstance(pspace2, CompoundPSpace) assert not isinstance(pspace3, CompoundPSpace) M = MultivariateNormalDistribution([1, 2], [[2, 1], [1, 2]]) raises(ValueError, lambda: CompoundPSpace('M', M)) Y = Normal('Y', X, 6) assert isinstance(Y.pspace, CompoundPSpace) assert Y.pspace.distribution == CompoundDistribution(NormalDistribution(X, 6)) assert Y.pspace.domain.set == Interval(-oo, oo)
def test_BernoulliProcess(): B = BernoulliProcess("B", p=0.6, success=1, failure=0) assert B.state_space == FiniteSet(0, 1) assert B.index_set == S.Naturals0 assert B.success == 1 assert B.failure == 0 X = BernoulliProcess("X", p=Rational(1, 3), success='H', failure='T') assert X.state_space == FiniteSet('H', 'T') H, T = symbols("H,T") assert E(X[1] + X[2] * X[3] ) == H**2 / 9 + 4 * H * T / 9 + H / 3 + 4 * T**2 / 9 + 2 * T / 3 t, x = symbols('t, x', positive=True, integer=True) assert isinstance(B[t], RandomIndexedSymbol) raises(ValueError, lambda: BernoulliProcess("X", p=1.1, success=1, failure=0)) raises(NotImplementedError, lambda: B(t)) raises(IndexError, lambda: B[-3]) assert B.joint_distribution(B[3], B[9]) == JointDistributionHandmade( Lambda( (B[3], B[9]), Piecewise((0.6, Eq(B[3], 1)), (0.4, Eq(B[3], 0)), (0, True)) * Piecewise((0.6, Eq(B[9], 1)), (0.4, Eq(B[9], 0)), (0, True)))) assert B.joint_distribution(2, B[4]) == JointDistributionHandmade( Lambda( (B[2], B[4]), Piecewise((0.6, Eq(B[2], 1)), (0.4, Eq(B[2], 0)), (0, True)) * Piecewise((0.6, Eq(B[4], 1)), (0.4, Eq(B[4], 0)), (0, True)))) # Test for the sum distribution of Bernoulli Process RVs Y = B[1] + B[2] + B[3] assert P(Eq(Y, 0)).round(2) == Float(0.06, 1) assert P(Eq(Y, 2)).round(2) == Float(0.43, 2) assert P(Eq(Y, 4)).round(2) == 0 assert P(Gt(Y, 1)).round(2) == Float(0.65, 2) # Test for independency of each Random Indexed variable assert P(Eq(B[1], 0) & Eq(B[2], 1) & Eq(B[3], 0) & Eq(B[4], 1)).round(2) == Float(0.06, 1) assert E(2 * B[1] + B[2]).round(2) == Float(1.80, 3) assert E(2 * B[1] + B[2] + 5).round(2) == Float(6.80, 3) assert E(B[2] * B[4] + B[10]).round(2) == Float(0.96, 2) assert E(B[2] > 0, Eq(B[1], 1) & Eq(B[2], 1)).round(2) == Float(0.60, 2) assert E(B[1]) == 0.6 assert P(B[1] > 0).round(2) == Float(0.60, 2) assert P(B[1] < 1).round(2) == Float(0.40, 2) assert P(B[1] > 0, B[2] <= 1).round(2) == Float(0.60, 2) assert P(B[12] * B[5] > 0).round(2) == Float(0.36, 2) assert P(B[12] * B[5] > 0, B[4] < 1).round(2) == Float(0.36, 2) assert P(Eq(B[2], 1), B[2] > 0) == 1 assert P(Eq(B[5], 3)) == 0 assert P(Eq(B[1], 1), B[1] < 0) == 0 assert P(B[2] > 0, Eq(B[2], 1)) == 1 assert P(B[2] < 0, Eq(B[2], 1)) == 0 assert P(B[2] > 0, B[2] == 7) == 0 assert P(B[5] > 0, B[5]) == BernoulliDistribution(0.6, 0, 1) raises(ValueError, lambda: P(3)) raises(ValueError, lambda: P(B[3] > 0, 3)) # test issue 19456 expr = Sum(B[t], (t, 0, 4)) expr2 = Sum(B[t], (t, 1, 3)) expr3 = Sum(B[t]**2, (t, 1, 3)) assert expr.doit() == B[0] + B[1] + B[2] + B[3] + B[4] assert expr2.doit() == Y assert expr3.doit() == B[1]**2 + B[2]**2 + B[3]**2 assert B[2 * t].free_symbols == {B[2 * t], t} assert B[4].free_symbols == {B[4]} assert B[x * t].free_symbols == {B[x * t], x, t} #test issue 20078 assert (2 * B[t] + 3 * B[t]).simplify() == 5 * B[t] assert (2 * B[t] - 3 * B[t]).simplify() == -B[t] assert (2 * (0.25 * B[t])).simplify() == 0.5 * B[t] assert (2 * B[t] * 0.25 * B[t]).simplify() == 0.5 * B[t]**2 assert (B[t]**2 + B[t]**3).simplify() == (B[t] + 1) * B[t]**2
def probability(condition, given_condition=None, numsamples=None, evaluate=True, **kwargs): """ Probability that a condition is true, optionally given a second condition Parameters ========== condition : Combination of Relationals containing RandomSymbols The condition of which you want to compute the probability given_condition : Combination of Relationals containing RandomSymbols A conditional expression. P(X > 1, X > 0) is expectation of X > 1 given X > 0 numsamples : int Enables sampling and approximates the probability with this many samples evaluate : Bool (defaults to True) In case of continuous systems return unevaluated integral Examples ======== >>> from sympy.stats import P, Die >>> from sympy import Eq >>> X, Y = Die('X', 6), Die('Y', 6) >>> P(X > 3) 1/2 >>> P(Eq(X, 5), X > 2) # Probability that X == 5 given that X > 2 1/4 >>> P(X > Y) 5/12 """ condition = sympify(condition) given_condition = sympify(given_condition) if condition.has(RandomIndexedSymbol): return pspace(condition).probability(condition, given_condition, evaluate, **kwargs) if isinstance(given_condition, RandomSymbol): condrv = random_symbols(condition) if len(condrv) == 1 and condrv[0] == given_condition: from sympy.stats.frv_types import BernoulliDistribution return BernoulliDistribution(probability(condition), 0, 1) if any([dependent(rv, given_condition) for rv in condrv]): from sympy.stats.symbolic_probability import Probability return Probability(condition, given_condition) else: return probability(condition) if given_condition is not None and \ not isinstance(given_condition, (Relational, Boolean)): raise ValueError( "%s is not a relational or combination of relationals" % (given_condition)) if given_condition == False: return S.Zero if not isinstance(condition, (Relational, Boolean)): raise ValueError( "%s is not a relational or combination of relationals" % (condition)) if condition is S.true: return S.One if condition is S.false: return S.Zero if numsamples: return sampling_P(condition, given_condition, numsamples=numsamples, **kwargs) if given_condition is not None: # If there is a condition # Recompute on new conditional expr return probability(given(condition, given_condition, **kwargs), **kwargs) # Otherwise pass work off to the ProbabilitySpace result = pspace(condition).probability(condition, **kwargs) if evaluate and hasattr(result, 'doit'): return result.doit() else: return result
def test_BernoulliProcess(): B = BernoulliProcess("B", p=0.6, success=1, failure=0) assert B.state_space == FiniteSet(0, 1) assert B.index_set == S.Naturals0 assert B.success == 1 assert B.failure == 0 X = BernoulliProcess("X", p=Rational(1, 3), success="H", failure="T") assert X.state_space == FiniteSet("H", "T") H, T = symbols("H,T") assert (E(X[1] + X[2] * X[3]) == H**2 / 9 + 4 * H * T / 9 + H / 3 + 4 * T**2 / 9 + 2 * T / 3) t = symbols("t", positive=True, integer=True) assert isinstance(B[t], RandomIndexedSymbol) raises(ValueError, lambda: BernoulliProcess("X", p=1.1, success=1, failure=0)) raises(NotImplementedError, lambda: B(t)) raises(IndexError, lambda: B[-3]) assert B.joint_distribution(B[3], B[9]) == JointDistributionHandmade( Lambda( (B[3], B[9]), Piecewise((0.6, Eq(B[3], 1)), (0.4, Eq(B[3], 0)), (0, True)) * Piecewise((0.6, Eq(B[9], 1)), (0.4, Eq(B[9], 0)), (0, True)), )) assert B.joint_distribution(2, B[4]) == JointDistributionHandmade( Lambda( (B[2], B[4]), Piecewise((0.6, Eq(B[2], 1)), (0.4, Eq(B[2], 0)), (0, True)) * Piecewise((0.6, Eq(B[4], 1)), (0.4, Eq(B[4], 0)), (0, True)), )) # Test for the sum distribution of Bernoulli Process RVs Y = B[1] + B[2] + B[3] assert P(Eq(Y, 0)).round(2) == Float(0.06, 1) assert P(Eq(Y, 2)).round(2) == Float(0.43, 2) assert P(Eq(Y, 4)).round(2) == 0 assert P(Gt(Y, 1)).round(2) == Float(0.65, 2) # Test for independency of each Random Indexed variable assert P(Eq(B[1], 0) & Eq(B[2], 1) & Eq(B[3], 0) & Eq(B[4], 1)).round(2) == Float(0.06, 1) assert E(2 * B[1] + B[2]).round(2) == Float(1.80, 3) assert E(2 * B[1] + B[2] + 5).round(2) == Float(6.80, 3) assert E(B[2] * B[4] + B[10]).round(2) == Float(0.96, 2) assert E(B[2] > 0, Eq(B[1], 1) & Eq(B[2], 1)).round(2) == Float(0.60, 2) assert E(B[1]) == 0.6 assert P(B[1] > 0).round(2) == Float(0.60, 2) assert P(B[1] < 1).round(2) == Float(0.40, 2) assert P(B[1] > 0, B[2] <= 1).round(2) == Float(0.60, 2) assert P(B[12] * B[5] > 0).round(2) == Float(0.36, 2) assert P(B[12] * B[5] > 0, B[4] < 1).round(2) == Float(0.36, 2) assert P(Eq(B[2], 1), B[2] > 0) == 1 assert P(Eq(B[5], 3)) == 0 assert P(Eq(B[1], 1), B[1] < 0) == 0 assert P(B[2] > 0, Eq(B[2], 1)) == 1 assert P(B[2] < 0, Eq(B[2], 1)) == 0 assert P(B[2] > 0, B[2] == 7) == 0 assert P(B[5] > 0, B[5]) == BernoulliDistribution(0.6, 0, 1) raises(ValueError, lambda: P(3)) raises(ValueError, lambda: P(B[3] > 0, 3))
def distribution(self): return BernoulliDistribution(self.p)