2015-11-23 14 views
6

Czy można manipulować wyrażeniami statystycznymi w SymPy bez określania rozkładów zmiennych losowych?Praca z wyrażeń statystycznych w SymPy bez określania dystrybucji

Na przykład, chciałbym pracować z dwiema zmiennymi losowymi, X i Y i móc zapytać SymPy rozszerzyć wyrażenie Var(X + Y), dostając odpowiedź Var(X) + Var(Y) + 2 Cov(X,Y).

Chciałbym również móc wprowadzić ograniczenia w dystrybucji X i Y, na przykład informując SymPy, że Cov(X, Y) = 0.

Czy to w ogóle możliwe w SymPy? Jeśli nie, czy istnieje inny pakiet, który może to zrobić?

+0

Wygląda sympy.stats zbudowana jest wokół mający wyraźne dystrybucje z wyraźnymi formacie PDF. Myślę, że najbliżej można uzyskać niestandardową dystrybucję z pdf 'f (x)', gdzie 'f = Funkcja (" f ') 'jest niezdefiniowaną funkcją. – asmeurer

+0

Zobacz na przykład https://stackoverflow.com/questions/32981363/how-to-create-a-rician-random-variable/32998623#32998623. Nie jestem pewien, czy możesz uzyskać tę tożsamość, czy nie. – asmeurer

+0

_variance_ w _sympy.stats_ spróbuje ocenić całkę, nie tworzy wyrażenia. Możesz spróbować _variance (X, assess = False) _, ale to spowoduje tylko nieocenioną całkę. Myślę, że musimy zdefiniować klasę _Variance_ (capital V) na symboliczną formułę. –

Odpowiedz

0

Można zrobić coś takiego:

import itertools 
from sympy.stats.rv import RandomSymbol 
from sympy.stats import * 

class Variance(Expr): 

    def __new__(cls, arg, **kwargs): 
     return Expr.__new__(cls, arg) 

    def doit(self, **kwargs): 
     return variance(self.args[0], **kwargs) 

    def var_expansion(self): 
     if isinstance(self.args[0], Add): 
      nonrv = [] 
      rv = [] 
      for a in self.args[0].args: 
       if isinstance(a, RandomSymbol): 
        rv.append(a) 
      variances = Add(*map(Variance, rv)) 
      map_to_covar = lambda x: Function("Covariance")(*x) 
      covariances = Add(*map(map_to_covar, itertools.combinations(rv, 2))) 
      return variances + covariances 
     return self 

funkcji .var_expansion() robi to, co chcesz.

Przykład:

In [2]: z = Symbol('z') 

In [3]: X = Normal('X', 3, 4) 

In [5]: Y = Normal('Y', 1, 2) 

In [6]: Variance(X) 
Out[6]: Variance(X) 

In [7]: Variance(X + z) 
Out[7]: Variance(z + X) 

In [8]: Variance(X).var_expansion() 
Out[8]: Variance(X) 

In [9]: Variance(X + z).var_expansion() 
Out[9]: Variance(X) 

In [10]: Variance(X + Y).var_expansion() 
Out[10]: Covariance(X, Y) + Variance(X) + Variance(Y) 

Niestety, dużo więcej pracy jest wymagane do wdrożenia wszystkich jego właściwości.

Aby wykonać obliczenie wariancji:

In [14]: Variance(X).doit() 
Out[14]: 16 

Aby uzyskać integralną wyrażenie:

In [18]: Variance(X).doit(evaluate=False) 
Out[18]: 
∞              
⌠              
⎮          2    
⎮  ⎛ ∞      ⎞     
⎮  ⎜ ⌠      ⎟     
⎮  ⎜ ⎮     2 ⎟     
⎮  ⎜ ⎮   -(X - 3)  ⎟   2  
⎮  ⎜ ⎮   ────────── ⎟ -(X - 3)  
⎮  ⎜ ⎮ ___  32  ⎟ ────────── 
⎮ ___ ⎜ ⎮ ╲╱ 2 ⋅X⋅ℯ    ⎟  32  
⎮ ╲╱ 2 ⋅⎜X - ⎮ ─────────────────── dX⎟ ⋅ℯ    
⎮  ⎜ ⎮   ___   ⎟     
⎮  ⎜ ⎮  8⋅╲╱ π   ⎟     
⎮  ⎜ ⌡      ⎟     
⎮  ⎝ -∞      ⎠     
⎮ ────────────────────────────────────────────────── dX 
⎮       ___       
⎮      8⋅╲╱ π       
⌡              
-∞ 
Powiązane problemy