def doit(self, **hints):
        if self.limits:
            function = self.function
            for limit in self.limits:
                x, distribution = limit
                _x = x.copy(distribution=distribution)
                expr = function._subs(x, _x)
                if expr.is_Conditioned:
                    expr = expr.doit()
                if not expr.is_random:  # expr isn't random?
                    return expr
                ps = pspace(expr)
                if ps == PSpace():
                    return self.func(expr)
                # Otherwise case is simple, pass work off to the ProbabilitySpace
                function = ps.compute_expectation(expr, evaluate=True)
                if hasattr(function, 'doit'):
                    function = function.doit(**hints)
            return function
        else:
            deep = hints.get('deep', True)
            expr = self.args[0]
            numsamples = hints.get('numsamples', False)
            for_rewrite = not hints.get('for_rewrite', False)

            if deep:
                expr = expr.doit(**hints)

            if not expr.is_random or isinstance(
                    expr, Expectation):  # expr isn't random?
                return expr
            if numsamples:  # Computing by monte carlo sampling?
                evalf = hints.get('evalf', True)
                return sampling_E(expr, numsamples=numsamples, evalf=evalf)

            if expr.has(RandomIndexedSymbol):
                return pspace(expr).compute_expectation(expr)

            # A few known statements for efficiency

            if expr.is_Add:  # We know that E is Linear
                return Add(*[
                    self.func(arg).doit(**hints)
                    if not isinstance(arg, Expectation) else self.func(arg)
                    for arg in expr.args
                ])
            if expr.is_Mul:
                if expr.atoms(Expectation):
                    return expr

            ps = pspace(expr)
            if ps == PSpace():
                return self.func(expr)
            # Otherwise case is simple, pass work off to the ProbabilitySpace
            result = ps.compute_expectation(expr, evaluate=for_rewrite)
            if hasattr(result, 'doit') and for_rewrite:
                return result.doit(**hints)
            else:
                return result
Esempio n. 2
0
    def doit(self, **hints):
        deep = hints.get('deep', True)
        condition = self._condition
        expr = self.args[0]
        numsamples = hints.get('numsamples', False)
        for_rewrite = not hints.get('for_rewrite', False)

        if deep:
            expr = expr.doit(**hints)

        if not is_random(expr) or isinstance(
                expr, Expectation):  # expr isn't random?
            return expr
        if numsamples:  # Computing by monte carlo sampling?
            evalf = hints.get('evalf', True)
            return sampling_E(expr,
                              condition,
                              numsamples=numsamples,
                              evalf=evalf)

        if expr.has(RandomIndexedSymbol):
            return pspace(expr).compute_expectation(expr, condition)

        # Create new expr and recompute E
        if condition is not None:  # If there is a condition
            return self.func(given(expr, condition)).doit(**hints)

        # A few known statements for efficiency

        if expr.is_Add:  # We know that E is Linear
            return Add(*[
                self.func(arg, condition).doit(
                    **hints) if not isinstance(arg, Expectation) else self.
                func(arg, condition) for arg in expr.args
            ])
        if expr.is_Mul:
            if expr.atoms(Expectation):
                return expr

        if pspace(expr) == PSpace():
            return self.func(expr)
        # Otherwise case is simple, pass work off to the ProbabilitySpace
        result = pspace(expr).compute_expectation(expr, evaluate=for_rewrite)
        if hasattr(result, 'doit') and for_rewrite:
            return result.doit(**hints)
        else:
            return result