Ejemplo n.º 1
0
def test_variance_prop_with_covar():
    x, y, z = symbols('x y z')
    phi, t = consts = symbols('phi t')
    a = RandomSymbol(x)
    var_x = Variance(a)
    b = RandomSymbol(y)
    var_y = Variance(b)
    c = RandomSymbol(z)
    var_z = Variance(c)
    covar_x_y = Covariance(a, b)
    covar_x_z = Covariance(a, c)
    covar_y_z = Covariance(b, c)
    cases = {
        x + y: var_x + var_y + 2*covar_x_y,
        a + y: var_x + var_y + 2*covar_x_y,
        x + y + z: var_x + var_y + var_z + \
                   2*covar_x_y + 2*covar_x_z + 2*covar_y_z,
        2*x: 4*var_x,
        x*y: var_x*y**2 + var_y*x**2 + 2*covar_x_y/(x*y),
        1/x: var_x/x**4,
        exp(x): var_x*exp(2*x),
        exp(2*x): 4*var_x*exp(4*x),
        exp(-x*t): t**2*var_x*exp(-2*t*x),
        }
    for inp, out in cases.items():
        obs = variance_prop(inp, consts=consts, include_covar=True)
        assert out == obs
Ejemplo n.º 2
0
def variance(X, condition=None, **kwargs):
    """
    Variance of a random expression

    Expectation of (X-E(X))**2

    Examples
    ========

    >>> from sympy.stats import Die, Bernoulli, variance
    >>> from sympy import simplify, Symbol

    >>> X = Die('X', 6)
    >>> p = Symbol('p')
    >>> B = Bernoulli('B', p, 1, 0)

    >>> variance(2*X)
    35/3

    >>> simplify(variance(B))
    p*(1 - p)
    """
    if is_random(X) and pspace(X) == PSpace():
        from sympy.stats.symbolic_probability import Variance
        return Variance(X, condition)

    return cmoment(X, 2, condition, **kwargs)
Ejemplo n.º 3
0
    def expand(self, **hints):
        arg = self.args[0]
        condition = self._condition

        if not is_random(arg):
            return ZeroMatrix(*self.shape)

        if isinstance(arg, RandomSymbol):
            return self
        elif isinstance(arg, Add):
            rv = []
            for a in arg.args:
                if is_random(a):
                    rv.append(a)
            variances = Add(
                *map(lambda xv: Variance(xv, condition).expand(), rv))
            map_to_covar = lambda x: 2 * Covariance(*x, condition=condition
                                                    ).expand()
            covariances = Add(
                *map(map_to_covar, itertools.combinations(rv, 2)))
            return variances + covariances
        elif isinstance(arg, (Mul, MatMul)):
            nonrv = []
            rv = []
            for a in arg.args:
                if is_random(a):
                    rv.append(a)
                else:
                    nonrv.append(a)
            if len(rv) == 0:
                return ZeroMatrix(*self.shape)
            # Avoid possible infinite loops with MatMul:
            if len(nonrv) == 0:
                return self
            # Variance of many multiple matrix products is not implemented:
            if len(rv) > 1:
                return self
            return Mul.fromiter(nonrv) * Variance(
                Mul.fromiter(rv),
                condition) * (Mul.fromiter(nonrv)).transpose()

        # this expression contains a RandomSymbol somehow:
        return self
Ejemplo n.º 4
0
def test_variance_prop():
    x, y, z = symbols('x y z')
    phi, t = consts = symbols('phi t')
    a = RandomSymbol(x)
    var_x = Variance(a)
    var_y = Variance(RandomSymbol(y))
    var_z = Variance(RandomSymbol(z))
    f = Function('f')(x)
    cases = {
        x + y: var_x + var_y,
        a + y: var_x + var_y,
        x + y + z: var_x + var_y + var_z,
        2*x: 4*var_x,
        x*y: var_x*y**2 + var_y*x**2,
        1/x: var_x/x**4,
        x/y: (var_x*y**2 + var_y*x**2)/y**4,
        exp(x): var_x*exp(2*x),
        exp(2*x): 4*var_x*exp(4*x),
        exp(-x*t): t**2*var_x*exp(-2*t*x),
        f: Variance(f),
        }
    for inp, out in cases.items():
        obs = variance_prop(inp, consts=consts)
        assert out == obs
Ejemplo n.º 5
0
def variance_prop(expr, consts=(), include_covar=False):
    r"""Symbolically propagates variance (`\sigma^2`) for expressions.
    This is computed as as seen in [1]_.

    Parameters
    ==========
    expr : Expr
        A sympy expression to compute the variance for.
    consts : sequence of Symbols, optional
        Represents symbols that are known constants in the expr,
        and thus have zero variance. All symbols not in consts are
        assumed to be variant.
    include_covar : bool, optional
        Flag for whether or not to include covariances, default=False.

    Returns
    =======
    var_expr : Expr
        An expression for the total variance of the expr.
        The variance for the original symbols (e.g. x) are represented
        via instance of the Variance symbol (e.g. Variance(x)).

    Examples
    ========

    >>> from sympy import symbols, exp
    >>> from sympy.stats.error_prop import variance_prop
    >>> x, y = symbols('x y')

    >>> variance_prop(x + y)
    Variance(x) + Variance(y)

    >>> variance_prop(x * y)
    x**2*Variance(y) + y**2*Variance(x)

    >>> variance_prop(exp(2*x))
    4*exp(4*x)*Variance(x)

    References
    ==========
    .. [1] https://en.wikipedia.org/wiki/Propagation_of_uncertainty

    """
    args = expr.args
    if len(args) == 0:
        if expr in consts:
            return S(0)
        elif isinstance(expr, RandomSymbol):
            return Variance(expr).doit()
        elif isinstance(expr, Symbol):
            return Variance(RandomSymbol(expr)).doit()
        else:
            return S(0)
    nargs = len(args)
    var_args = list(
        map(variance_prop, args, repeat(consts, nargs),
            repeat(include_covar, nargs)))
    if isinstance(expr, Add):
        var_expr = Add(*var_args)
        if include_covar:
            terms = [2 * Covariance(_arg0_or_var(x), _arg0_or_var(y)).doit() \
                     for x, y in combinations(var_args, 2)]
            var_expr += Add(*terms)
    elif isinstance(expr, Mul):
        terms = [v / a**2 for a, v in zip(args, var_args)]
        var_expr = simplify(expr**2 * Add(*terms))
        if include_covar:
            terms = [2*Covariance(_arg0_or_var(x), _arg0_or_var(y)).doit()/(a*b) \
                     for (a, b), (x, y) in zip(combinations(args, 2),
                                               combinations(var_args, 2))]
            var_expr += Add(*terms)
    elif isinstance(expr, Pow):
        b = args[1]
        v = var_args[0] * (expr * b / args[0])**2
        var_expr = simplify(v)
    elif isinstance(expr, exp):
        var_expr = simplify(var_args[0] * expr**2)
    else:
        # unknown how to proceed, return variance of whole expr.
        var_expr = Variance(expr)
    return var_expr
Ejemplo n.º 6
0
def test_literal_probability():
    X = Normal('X', 2, 3)
    Y = Normal('Y', 3, 4)
    Z = Poisson('Z', 4)
    W = Poisson('W', 3)
    x, y, w, z = symbols('x, y, w, z')

    assert Probability(X > 0).doit() == probability(X > 0)
    assert Probability(X > x).doit() == probability(X > x)

    assert Expectation(X).doit() == expectation(X)
    assert Expectation(X**2).doit() == expectation(X**2)
    assert Expectation(x*X) == x*Expectation(X)
    assert Expectation(2*X + 3*Y + z*X*Y) == 2*Expectation(X) + 3*Expectation(Y) + z*Expectation(X*Y)
    assert Expectation(2*X + 3*Y + z*X*Y, evaluate=False).args == (2*X + 3*Y + z*X*Y,)
    assert Expectation(sin(X)) == Expectation(sin(X), evaluate=False)
    assert Expectation(2*x*sin(X)*Y + y*X**2 + z*X*Y) == 2*x*Expectation(sin(X)*Y) + y*Expectation(X**2) + z*Expectation(X*Y)

    assert Variance(w) == 0
    assert Variance(X).doit() == variance(X)
    assert Variance(X + z) == Variance(X)
    assert Variance(X*Y).args == (Mul(X, Y),)
    assert type(Variance(X*Y)) == Variance
    assert Variance(z*X) == z**2*Variance(X)
    assert Variance(X + Y) == Variance(X) + Variance(Y) + 2*Covariance(X, Y)
    assert Variance(X + Y + Z + W) == (Variance(X) + Variance(Y) + Variance(Z) + Variance(W) +
                                       2 * Covariance(X, Y) + 2 * Covariance(X, Z) + 2 * Covariance(X, W) +
                                       2 * Covariance(Y, Z) + 2 * Covariance(Y, W) + 2 * Covariance(W, Z))
    assert Variance(X**2).doit() == variance(X**2)
    assert Variance(X**2, evaluate=False) == Variance(X**2)
    assert Variance(x*X**2) == x**2*Variance(X**2)
    assert Variance(sin(X)).args == (sin(X),)
    assert Variance(sin(X), evaluate=False) == Variance(sin(X))
    assert Variance(x*sin(X)) == x**2*Variance(sin(X))

    assert Covariance(w, z) == 0
    assert Covariance(X, w) == 0
    assert Covariance(w, X) == 0
    assert Covariance(X, Y).args == (X, Y)
    assert type(Covariance(X, Y)) == Covariance
    assert Covariance(z*X + 3, Y) == z*Covariance(X, Y)
    assert Covariance(X, X) == Variance(X)
    assert Covariance(z*X + 3, w*Y + 4) == w*z*Covariance(X,Y)
    assert Covariance(X, Y) == Covariance(Y, X)
    assert Covariance(X + Y, Z + W) == Covariance(W, X) + Covariance(W, Y) + Covariance(X, Z) + Covariance(Y, Z)
    assert Covariance(x*X + y*Y, z*Z + w*W) == (x*w*Covariance(W, X) + w*y*Covariance(W, Y) +
                                                x*z*Covariance(X, Z) + y*z*Covariance(Y, Z))
    assert Covariance(x*X**2 + y*sin(Y), z*Y*Z**2 + w*W) == (w*x*Covariance(W, X**2) + w*y*Covariance(sin(Y), W) +
                                                        x*z*Covariance(Y*Z**2, X**2) + y*z*Covariance(Y*Z**2, sin(Y)))
    assert Covariance(X, X**2) == Covariance(X, X**2, evaluate=False)
    assert Covariance(X, sin(X)) == Covariance(sin(X), X, evaluate=False)
    assert Covariance(X**2, sin(X)*Y) == Covariance(sin(X)*Y, X**2, evaluate=False)