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⋅╲╱ π
⌡
-∞
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
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
_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łę. –