def test_JointEigenDistribution(): A = Matrix([[Normal('A00', 0, 1), Normal('A01', 1, 1)], [Beta('A10', 1, 1), Beta('A11', 1, 1)]]) JointEigenDistribution(A) == \ JointDistributionHandmade(-sqrt(A[0, 0]**2 - 2*A[0, 0]*A[1, 1] + 4*A[0, 1]*A[1, 0] + A[1, 1]**2)/2 + A[0, 0]/2 + A[1, 1]/2, sqrt(A[0, 0]**2 - 2*A[0, 0]*A[1, 1] + 4*A[0, 1]*A[1, 0] + A[1, 1]**2)/2 + A[0, 0]/2 + A[1, 1]/2) raises(ValueError, lambda: JointEigenDistribution(Matrix([[1, 0], [2, 1]])))
def JointRV(symbol, pdf, _set=None): """ Create a Joint Random Variable where each of its component is conitinuous, given the following: -- a symbol -- a PDF in terms of indexed symbols of the symbol given as the first argument NOTE: As of now, the set for each component for a `JointRV` is equal to the set of all integers, which can not be changed. Examples ======== >>> from sympy import symbols, exp, pi, Indexed, S >>> from sympy.stats import density >>> from sympy.stats.joint_rv_types import JointRV >>> x1, x2 = (Indexed('x', i) for i in (1, 2)) >>> pdf = exp(-x1**2/2 + x1 - x2**2/2 - S(1)/2)/(2*pi) >>> N1 = JointRV('x', pdf) #Multivariate Normal distribution >>> density(N1)(1, 2) exp(-2)/(2*pi) Returns ======= A RandomSymbol. """ #TODO: Add support for sets provided by the user symbol = sympify(symbol) syms = list(i for i in pdf.free_symbols if isinstance(i, Indexed) and i.base == IndexedBase(symbol)) syms = tuple(sorted(syms, key=lambda index: index.args[1])) _set = S.Reals**len(syms) pdf = Lambda(syms, pdf) dist = JointDistributionHandmade(pdf, _set) jrv = JointPSpace(symbol, dist).value rvs = random_symbols(pdf) if len(rvs) != 0: dist = MarginalDistribution(dist, (jrv, )) return JointPSpace(symbol, dist).value return jrv
def joint_distribution(self, *args): """ Computes the joint distribution of the random indexed variables. Parameters ========== args: iterable The finite list of random indexed variables/the key of a stochastic process whose joint distribution has to be computed. Returns ======= JointDistribution The joint distribution of the list of random indexed variables. An unevaluated object is returned if it is not possible to compute the joint distribution. Raises ====== ValueError: When the arguments passed are not of type RandomIndexSymbol or Number. """ args = list(args) for i, arg in enumerate(args): if S(arg).is_Number: if self.index_set.is_subset(S.Integers): args[i] = self.__getitem__(arg) else: args[i] = self.__call__(arg) elif not isinstance(arg, RandomIndexedSymbol): raise ValueError("Expected a RandomIndexedSymbol or " "key not %s" % (type(arg))) if (args[0].pspace.distribution == None ): # checks if there is any distribution available return JointDistribution(*args) pdf = Lambda( tuple(args), expr=Mul.fromiter(arg.pspace.process.density(arg) for arg in args), ) return JointDistributionHandmade(pdf)
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))