图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

687 lines
22 KiB

  1. import itertools
  2. from sympy.concrete.summations import Sum
  3. from sympy.core.add import Add
  4. from sympy.core.expr import Expr
  5. from sympy.core.function import expand as _expand
  6. from sympy.core.mul import Mul
  7. from sympy.core.relational import Eq
  8. from sympy.core.singleton import S
  9. from sympy.core.symbol import Symbol
  10. from sympy.integrals.integrals import Integral
  11. from sympy.logic.boolalg import Not
  12. from sympy.core.parameters import global_parameters
  13. from sympy.core.sorting import default_sort_key
  14. from sympy.core.sympify import _sympify
  15. from sympy.core.relational import Relational
  16. from sympy.logic.boolalg import Boolean
  17. from sympy.stats import variance, covariance
  18. from sympy.stats.rv import (RandomSymbol, pspace, dependent,
  19. given, sampling_E, RandomIndexedSymbol, is_random,
  20. PSpace, sampling_P, random_symbols)
  21. __all__ = ['Probability', 'Expectation', 'Variance', 'Covariance']
  22. @is_random.register(Expr)
  23. def _(x):
  24. atoms = x.free_symbols
  25. if len(atoms) == 1 and next(iter(atoms)) == x:
  26. return False
  27. return any(is_random(i) for i in atoms)
  28. @is_random.register(RandomSymbol) # type: ignore
  29. def _(x):
  30. return True
  31. class Probability(Expr):
  32. """
  33. Symbolic expression for the probability.
  34. Examples
  35. ========
  36. >>> from sympy.stats import Probability, Normal
  37. >>> from sympy import Integral
  38. >>> X = Normal("X", 0, 1)
  39. >>> prob = Probability(X > 1)
  40. >>> prob
  41. Probability(X > 1)
  42. Integral representation:
  43. >>> prob.rewrite(Integral)
  44. Integral(sqrt(2)*exp(-_z**2/2)/(2*sqrt(pi)), (_z, 1, oo))
  45. Evaluation of the integral:
  46. >>> prob.evaluate_integral()
  47. sqrt(2)*(-sqrt(2)*sqrt(pi)*erf(sqrt(2)/2) + sqrt(2)*sqrt(pi))/(4*sqrt(pi))
  48. """
  49. def __new__(cls, prob, condition=None, **kwargs):
  50. prob = _sympify(prob)
  51. if condition is None:
  52. obj = Expr.__new__(cls, prob)
  53. else:
  54. condition = _sympify(condition)
  55. obj = Expr.__new__(cls, prob, condition)
  56. obj._condition = condition
  57. return obj
  58. def doit(self, **hints):
  59. condition = self.args[0]
  60. given_condition = self._condition
  61. numsamples = hints.get('numsamples', False)
  62. for_rewrite = not hints.get('for_rewrite', False)
  63. if isinstance(condition, Not):
  64. return S.One - self.func(condition.args[0], given_condition,
  65. evaluate=for_rewrite).doit(**hints)
  66. if condition.has(RandomIndexedSymbol):
  67. return pspace(condition).probability(condition, given_condition,
  68. evaluate=for_rewrite)
  69. if isinstance(given_condition, RandomSymbol):
  70. condrv = random_symbols(condition)
  71. if len(condrv) == 1 and condrv[0] == given_condition:
  72. from sympy.stats.frv_types import BernoulliDistribution
  73. return BernoulliDistribution(self.func(condition).doit(**hints), 0, 1)
  74. if any(dependent(rv, given_condition) for rv in condrv):
  75. return Probability(condition, given_condition)
  76. else:
  77. return Probability(condition).doit()
  78. if given_condition is not None and \
  79. not isinstance(given_condition, (Relational, Boolean)):
  80. raise ValueError("%s is not a relational or combination of relationals"
  81. % (given_condition))
  82. if given_condition == False or condition is S.false:
  83. return S.Zero
  84. if not isinstance(condition, (Relational, Boolean)):
  85. raise ValueError("%s is not a relational or combination of relationals"
  86. % (condition))
  87. if condition is S.true:
  88. return S.One
  89. if numsamples:
  90. return sampling_P(condition, given_condition, numsamples=numsamples)
  91. if given_condition is not None: # If there is a condition
  92. # Recompute on new conditional expr
  93. return Probability(given(condition, given_condition)).doit()
  94. # Otherwise pass work off to the ProbabilitySpace
  95. if pspace(condition) == PSpace():
  96. return Probability(condition, given_condition)
  97. result = pspace(condition).probability(condition)
  98. if hasattr(result, 'doit') and for_rewrite:
  99. return result.doit()
  100. else:
  101. return result
  102. def _eval_rewrite_as_Integral(self, arg, condition=None, **kwargs):
  103. return self.func(arg, condition=condition).doit(for_rewrite=True)
  104. _eval_rewrite_as_Sum = _eval_rewrite_as_Integral
  105. def evaluate_integral(self):
  106. return self.rewrite(Integral).doit()
  107. class Expectation(Expr):
  108. """
  109. Symbolic expression for the expectation.
  110. Examples
  111. ========
  112. >>> from sympy.stats import Expectation, Normal, Probability, Poisson
  113. >>> from sympy import symbols, Integral, Sum
  114. >>> mu = symbols("mu")
  115. >>> sigma = symbols("sigma", positive=True)
  116. >>> X = Normal("X", mu, sigma)
  117. >>> Expectation(X)
  118. Expectation(X)
  119. >>> Expectation(X).evaluate_integral().simplify()
  120. mu
  121. To get the integral expression of the expectation:
  122. >>> Expectation(X).rewrite(Integral)
  123. Integral(sqrt(2)*X*exp(-(X - mu)**2/(2*sigma**2))/(2*sqrt(pi)*sigma), (X, -oo, oo))
  124. The same integral expression, in more abstract terms:
  125. >>> Expectation(X).rewrite(Probability)
  126. Integral(x*Probability(Eq(X, x)), (x, -oo, oo))
  127. To get the Summation expression of the expectation for discrete random variables:
  128. >>> lamda = symbols('lamda', positive=True)
  129. >>> Z = Poisson('Z', lamda)
  130. >>> Expectation(Z).rewrite(Sum)
  131. Sum(Z*lamda**Z*exp(-lamda)/factorial(Z), (Z, 0, oo))
  132. This class is aware of some properties of the expectation:
  133. >>> from sympy.abc import a
  134. >>> Expectation(a*X)
  135. Expectation(a*X)
  136. >>> Y = Normal("Y", 1, 2)
  137. >>> Expectation(X + Y)
  138. Expectation(X + Y)
  139. To expand the ``Expectation`` into its expression, use ``expand()``:
  140. >>> Expectation(X + Y).expand()
  141. Expectation(X) + Expectation(Y)
  142. >>> Expectation(a*X + Y).expand()
  143. a*Expectation(X) + Expectation(Y)
  144. >>> Expectation(a*X + Y)
  145. Expectation(a*X + Y)
  146. >>> Expectation((X + Y)*(X - Y)).expand()
  147. Expectation(X**2) - Expectation(Y**2)
  148. To evaluate the ``Expectation``, use ``doit()``:
  149. >>> Expectation(X + Y).doit()
  150. mu + 1
  151. >>> Expectation(X + Expectation(Y + Expectation(2*X))).doit()
  152. 3*mu + 1
  153. To prevent evaluating nested ``Expectation``, use ``doit(deep=False)``
  154. >>> Expectation(X + Expectation(Y)).doit(deep=False)
  155. mu + Expectation(Expectation(Y))
  156. >>> Expectation(X + Expectation(Y + Expectation(2*X))).doit(deep=False)
  157. mu + Expectation(Expectation(Y + Expectation(2*X)))
  158. """
  159. def __new__(cls, expr, condition=None, **kwargs):
  160. expr = _sympify(expr)
  161. if expr.is_Matrix:
  162. from sympy.stats.symbolic_multivariate_probability import ExpectationMatrix
  163. return ExpectationMatrix(expr, condition)
  164. if condition is None:
  165. if not is_random(expr):
  166. return expr
  167. obj = Expr.__new__(cls, expr)
  168. else:
  169. condition = _sympify(condition)
  170. obj = Expr.__new__(cls, expr, condition)
  171. obj._condition = condition
  172. return obj
  173. def expand(self, **hints):
  174. expr = self.args[0]
  175. condition = self._condition
  176. if not is_random(expr):
  177. return expr
  178. if isinstance(expr, Add):
  179. return Add.fromiter(Expectation(a, condition=condition).expand()
  180. for a in expr.args)
  181. expand_expr = _expand(expr)
  182. if isinstance(expand_expr, Add):
  183. return Add.fromiter(Expectation(a, condition=condition).expand()
  184. for a in expand_expr.args)
  185. elif isinstance(expr, Mul):
  186. rv = []
  187. nonrv = []
  188. for a in expr.args:
  189. if is_random(a):
  190. rv.append(a)
  191. else:
  192. nonrv.append(a)
  193. return Mul.fromiter(nonrv)*Expectation(Mul.fromiter(rv), condition=condition)
  194. return self
  195. def doit(self, **hints):
  196. deep = hints.get('deep', True)
  197. condition = self._condition
  198. expr = self.args[0]
  199. numsamples = hints.get('numsamples', False)
  200. for_rewrite = not hints.get('for_rewrite', False)
  201. if deep:
  202. expr = expr.doit(**hints)
  203. if not is_random(expr) or isinstance(expr, Expectation): # expr isn't random?
  204. return expr
  205. if numsamples: # Computing by monte carlo sampling?
  206. evalf = hints.get('evalf', True)
  207. return sampling_E(expr, condition, numsamples=numsamples, evalf=evalf)
  208. if expr.has(RandomIndexedSymbol):
  209. return pspace(expr).compute_expectation(expr, condition)
  210. # Create new expr and recompute E
  211. if condition is not None: # If there is a condition
  212. return self.func(given(expr, condition)).doit(**hints)
  213. # A few known statements for efficiency
  214. if expr.is_Add: # We know that E is Linear
  215. return Add(*[self.func(arg, condition).doit(**hints)
  216. if not isinstance(arg, Expectation) else self.func(arg, condition)
  217. for arg in expr.args])
  218. if expr.is_Mul:
  219. if expr.atoms(Expectation):
  220. return expr
  221. if pspace(expr) == PSpace():
  222. return self.func(expr)
  223. # Otherwise case is simple, pass work off to the ProbabilitySpace
  224. result = pspace(expr).compute_expectation(expr, evaluate=for_rewrite)
  225. if hasattr(result, 'doit') and for_rewrite:
  226. return result.doit(**hints)
  227. else:
  228. return result
  229. def _eval_rewrite_as_Probability(self, arg, condition=None, **kwargs):
  230. rvs = arg.atoms(RandomSymbol)
  231. if len(rvs) > 1:
  232. raise NotImplementedError()
  233. if len(rvs) == 0:
  234. return arg
  235. rv = rvs.pop()
  236. if rv.pspace is None:
  237. raise ValueError("Probability space not known")
  238. symbol = rv.symbol
  239. if symbol.name[0].isupper():
  240. symbol = Symbol(symbol.name.lower())
  241. else :
  242. symbol = Symbol(symbol.name + "_1")
  243. if rv.pspace.is_Continuous:
  244. return Integral(arg.replace(rv, symbol)*Probability(Eq(rv, symbol), condition), (symbol, rv.pspace.domain.set.inf, rv.pspace.domain.set.sup))
  245. else:
  246. if rv.pspace.is_Finite:
  247. raise NotImplementedError
  248. else:
  249. return Sum(arg.replace(rv, symbol)*Probability(Eq(rv, symbol), condition), (symbol, rv.pspace.domain.set.inf, rv.pspace.set.sup))
  250. def _eval_rewrite_as_Integral(self, arg, condition=None, **kwargs):
  251. return self.func(arg, condition=condition).doit(deep=False, for_rewrite=True)
  252. _eval_rewrite_as_Sum = _eval_rewrite_as_Integral # For discrete this will be Sum
  253. def evaluate_integral(self):
  254. return self.rewrite(Integral).doit()
  255. evaluate_sum = evaluate_integral
  256. class Variance(Expr):
  257. """
  258. Symbolic expression for the variance.
  259. Examples
  260. ========
  261. >>> from sympy import symbols, Integral
  262. >>> from sympy.stats import Normal, Expectation, Variance, Probability
  263. >>> mu = symbols("mu", positive=True)
  264. >>> sigma = symbols("sigma", positive=True)
  265. >>> X = Normal("X", mu, sigma)
  266. >>> Variance(X)
  267. Variance(X)
  268. >>> Variance(X).evaluate_integral()
  269. sigma**2
  270. Integral representation of the underlying calculations:
  271. >>> Variance(X).rewrite(Integral)
  272. Integral(sqrt(2)*(X - Integral(sqrt(2)*X*exp(-(X - mu)**2/(2*sigma**2))/(2*sqrt(pi)*sigma), (X, -oo, oo)))**2*exp(-(X - mu)**2/(2*sigma**2))/(2*sqrt(pi)*sigma), (X, -oo, oo))
  273. Integral representation, without expanding the PDF:
  274. >>> Variance(X).rewrite(Probability)
  275. -Integral(x*Probability(Eq(X, x)), (x, -oo, oo))**2 + Integral(x**2*Probability(Eq(X, x)), (x, -oo, oo))
  276. Rewrite the variance in terms of the expectation
  277. >>> Variance(X).rewrite(Expectation)
  278. -Expectation(X)**2 + Expectation(X**2)
  279. Some transformations based on the properties of the variance may happen:
  280. >>> from sympy.abc import a
  281. >>> Y = Normal("Y", 0, 1)
  282. >>> Variance(a*X)
  283. Variance(a*X)
  284. To expand the variance in its expression, use ``expand()``:
  285. >>> Variance(a*X).expand()
  286. a**2*Variance(X)
  287. >>> Variance(X + Y)
  288. Variance(X + Y)
  289. >>> Variance(X + Y).expand()
  290. 2*Covariance(X, Y) + Variance(X) + Variance(Y)
  291. """
  292. def __new__(cls, arg, condition=None, **kwargs):
  293. arg = _sympify(arg)
  294. if arg.is_Matrix:
  295. from sympy.stats.symbolic_multivariate_probability import VarianceMatrix
  296. return VarianceMatrix(arg, condition)
  297. if condition is None:
  298. obj = Expr.__new__(cls, arg)
  299. else:
  300. condition = _sympify(condition)
  301. obj = Expr.__new__(cls, arg, condition)
  302. obj._condition = condition
  303. return obj
  304. def expand(self, **hints):
  305. arg = self.args[0]
  306. condition = self._condition
  307. if not is_random(arg):
  308. return S.Zero
  309. if isinstance(arg, RandomSymbol):
  310. return self
  311. elif isinstance(arg, Add):
  312. rv = []
  313. for a in arg.args:
  314. if is_random(a):
  315. rv.append(a)
  316. variances = Add(*map(lambda xv: Variance(xv, condition).expand(), rv))
  317. map_to_covar = lambda x: 2*Covariance(*x, condition=condition).expand()
  318. covariances = Add(*map(map_to_covar, itertools.combinations(rv, 2)))
  319. return variances + covariances
  320. elif isinstance(arg, Mul):
  321. nonrv = []
  322. rv = []
  323. for a in arg.args:
  324. if is_random(a):
  325. rv.append(a)
  326. else:
  327. nonrv.append(a**2)
  328. if len(rv) == 0:
  329. return S.Zero
  330. return Mul.fromiter(nonrv)*Variance(Mul.fromiter(rv), condition)
  331. # this expression contains a RandomSymbol somehow:
  332. return self
  333. def _eval_rewrite_as_Expectation(self, arg, condition=None, **kwargs):
  334. e1 = Expectation(arg**2, condition)
  335. e2 = Expectation(arg, condition)**2
  336. return e1 - e2
  337. def _eval_rewrite_as_Probability(self, arg, condition=None, **kwargs):
  338. return self.rewrite(Expectation).rewrite(Probability)
  339. def _eval_rewrite_as_Integral(self, arg, condition=None, **kwargs):
  340. return variance(self.args[0], self._condition, evaluate=False)
  341. _eval_rewrite_as_Sum = _eval_rewrite_as_Integral
  342. def evaluate_integral(self):
  343. return self.rewrite(Integral).doit()
  344. class Covariance(Expr):
  345. """
  346. Symbolic expression for the covariance.
  347. Examples
  348. ========
  349. >>> from sympy.stats import Covariance
  350. >>> from sympy.stats import Normal
  351. >>> X = Normal("X", 3, 2)
  352. >>> Y = Normal("Y", 0, 1)
  353. >>> Z = Normal("Z", 0, 1)
  354. >>> W = Normal("W", 0, 1)
  355. >>> cexpr = Covariance(X, Y)
  356. >>> cexpr
  357. Covariance(X, Y)
  358. Evaluate the covariance, `X` and `Y` are independent,
  359. therefore zero is the result:
  360. >>> cexpr.evaluate_integral()
  361. 0
  362. Rewrite the covariance expression in terms of expectations:
  363. >>> from sympy.stats import Expectation
  364. >>> cexpr.rewrite(Expectation)
  365. Expectation(X*Y) - Expectation(X)*Expectation(Y)
  366. In order to expand the argument, use ``expand()``:
  367. >>> from sympy.abc import a, b, c, d
  368. >>> Covariance(a*X + b*Y, c*Z + d*W)
  369. Covariance(a*X + b*Y, c*Z + d*W)
  370. >>> Covariance(a*X + b*Y, c*Z + d*W).expand()
  371. a*c*Covariance(X, Z) + a*d*Covariance(W, X) + b*c*Covariance(Y, Z) + b*d*Covariance(W, Y)
  372. This class is aware of some properties of the covariance:
  373. >>> Covariance(X, X).expand()
  374. Variance(X)
  375. >>> Covariance(a*X, b*Y).expand()
  376. a*b*Covariance(X, Y)
  377. """
  378. def __new__(cls, arg1, arg2, condition=None, **kwargs):
  379. arg1 = _sympify(arg1)
  380. arg2 = _sympify(arg2)
  381. if arg1.is_Matrix or arg2.is_Matrix:
  382. from sympy.stats.symbolic_multivariate_probability import CrossCovarianceMatrix
  383. return CrossCovarianceMatrix(arg1, arg2, condition)
  384. if kwargs.pop('evaluate', global_parameters.evaluate):
  385. arg1, arg2 = sorted([arg1, arg2], key=default_sort_key)
  386. if condition is None:
  387. obj = Expr.__new__(cls, arg1, arg2)
  388. else:
  389. condition = _sympify(condition)
  390. obj = Expr.__new__(cls, arg1, arg2, condition)
  391. obj._condition = condition
  392. return obj
  393. def expand(self, **hints):
  394. arg1 = self.args[0]
  395. arg2 = self.args[1]
  396. condition = self._condition
  397. if arg1 == arg2:
  398. return Variance(arg1, condition).expand()
  399. if not is_random(arg1):
  400. return S.Zero
  401. if not is_random(arg2):
  402. return S.Zero
  403. arg1, arg2 = sorted([arg1, arg2], key=default_sort_key)
  404. if isinstance(arg1, RandomSymbol) and isinstance(arg2, RandomSymbol):
  405. return Covariance(arg1, arg2, condition)
  406. coeff_rv_list1 = self._expand_single_argument(arg1.expand())
  407. coeff_rv_list2 = self._expand_single_argument(arg2.expand())
  408. addends = [a*b*Covariance(*sorted([r1, r2], key=default_sort_key), condition=condition)
  409. for (a, r1) in coeff_rv_list1 for (b, r2) in coeff_rv_list2]
  410. return Add.fromiter(addends)
  411. @classmethod
  412. def _expand_single_argument(cls, expr):
  413. # return (coefficient, random_symbol) pairs:
  414. if isinstance(expr, RandomSymbol):
  415. return [(S.One, expr)]
  416. elif isinstance(expr, Add):
  417. outval = []
  418. for a in expr.args:
  419. if isinstance(a, Mul):
  420. outval.append(cls._get_mul_nonrv_rv_tuple(a))
  421. elif is_random(a):
  422. outval.append((S.One, a))
  423. return outval
  424. elif isinstance(expr, Mul):
  425. return [cls._get_mul_nonrv_rv_tuple(expr)]
  426. elif is_random(expr):
  427. return [(S.One, expr)]
  428. @classmethod
  429. def _get_mul_nonrv_rv_tuple(cls, m):
  430. rv = []
  431. nonrv = []
  432. for a in m.args:
  433. if is_random(a):
  434. rv.append(a)
  435. else:
  436. nonrv.append(a)
  437. return (Mul.fromiter(nonrv), Mul.fromiter(rv))
  438. def _eval_rewrite_as_Expectation(self, arg1, arg2, condition=None, **kwargs):
  439. e1 = Expectation(arg1*arg2, condition)
  440. e2 = Expectation(arg1, condition)*Expectation(arg2, condition)
  441. return e1 - e2
  442. def _eval_rewrite_as_Probability(self, arg1, arg2, condition=None, **kwargs):
  443. return self.rewrite(Expectation).rewrite(Probability)
  444. def _eval_rewrite_as_Integral(self, arg1, arg2, condition=None, **kwargs):
  445. return covariance(self.args[0], self.args[1], self._condition, evaluate=False)
  446. _eval_rewrite_as_Sum = _eval_rewrite_as_Integral
  447. def evaluate_integral(self):
  448. return self.rewrite(Integral).doit()
  449. class Moment(Expr):
  450. """
  451. Symbolic class for Moment
  452. Examples
  453. ========
  454. >>> from sympy import Symbol, Integral
  455. >>> from sympy.stats import Normal, Expectation, Probability, Moment
  456. >>> mu = Symbol('mu', real=True)
  457. >>> sigma = Symbol('sigma', positive=True)
  458. >>> X = Normal('X', mu, sigma)
  459. >>> M = Moment(X, 3, 1)
  460. To evaluate the result of Moment use `doit`:
  461. >>> M.doit()
  462. mu**3 - 3*mu**2 + 3*mu*sigma**2 + 3*mu - 3*sigma**2 - 1
  463. Rewrite the Moment expression in terms of Expectation:
  464. >>> M.rewrite(Expectation)
  465. Expectation((X - 1)**3)
  466. Rewrite the Moment expression in terms of Probability:
  467. >>> M.rewrite(Probability)
  468. Integral((x - 1)**3*Probability(Eq(X, x)), (x, -oo, oo))
  469. Rewrite the Moment expression in terms of Integral:
  470. >>> M.rewrite(Integral)
  471. Integral(sqrt(2)*(X - 1)**3*exp(-(X - mu)**2/(2*sigma**2))/(2*sqrt(pi)*sigma), (X, -oo, oo))
  472. """
  473. def __new__(cls, X, n, c=0, condition=None, **kwargs):
  474. X = _sympify(X)
  475. n = _sympify(n)
  476. c = _sympify(c)
  477. if condition is not None:
  478. condition = _sympify(condition)
  479. return super().__new__(cls, X, n, c, condition)
  480. else:
  481. return super().__new__(cls, X, n, c)
  482. def doit(self, **hints):
  483. return self.rewrite(Expectation).doit(**hints)
  484. def _eval_rewrite_as_Expectation(self, X, n, c=0, condition=None, **kwargs):
  485. return Expectation((X - c)**n, condition)
  486. def _eval_rewrite_as_Probability(self, X, n, c=0, condition=None, **kwargs):
  487. return self.rewrite(Expectation).rewrite(Probability)
  488. def _eval_rewrite_as_Integral(self, X, n, c=0, condition=None, **kwargs):
  489. return self.rewrite(Expectation).rewrite(Integral)
  490. class CentralMoment(Expr):
  491. """
  492. Symbolic class Central Moment
  493. Examples
  494. ========
  495. >>> from sympy import Symbol, Integral
  496. >>> from sympy.stats import Normal, Expectation, Probability, CentralMoment
  497. >>> mu = Symbol('mu', real=True)
  498. >>> sigma = Symbol('sigma', positive=True)
  499. >>> X = Normal('X', mu, sigma)
  500. >>> CM = CentralMoment(X, 4)
  501. To evaluate the result of CentralMoment use `doit`:
  502. >>> CM.doit().simplify()
  503. 3*sigma**4
  504. Rewrite the CentralMoment expression in terms of Expectation:
  505. >>> CM.rewrite(Expectation)
  506. Expectation((X - Expectation(X))**4)
  507. Rewrite the CentralMoment expression in terms of Probability:
  508. >>> CM.rewrite(Probability)
  509. Integral((x - Integral(x*Probability(True), (x, -oo, oo)))**4*Probability(Eq(X, x)), (x, -oo, oo))
  510. Rewrite the CentralMoment expression in terms of Integral:
  511. >>> CM.rewrite(Integral)
  512. Integral(sqrt(2)*(X - Integral(sqrt(2)*X*exp(-(X - mu)**2/(2*sigma**2))/(2*sqrt(pi)*sigma), (X, -oo, oo)))**4*exp(-(X - mu)**2/(2*sigma**2))/(2*sqrt(pi)*sigma), (X, -oo, oo))
  513. """
  514. def __new__(cls, X, n, condition=None, **kwargs):
  515. X = _sympify(X)
  516. n = _sympify(n)
  517. if condition is not None:
  518. condition = _sympify(condition)
  519. return super().__new__(cls, X, n, condition)
  520. else:
  521. return super().__new__(cls, X, n)
  522. def doit(self, **hints):
  523. return self.rewrite(Expectation).doit(**hints)
  524. def _eval_rewrite_as_Expectation(self, X, n, condition=None, **kwargs):
  525. mu = Expectation(X, condition, **kwargs)
  526. return Moment(X, n, mu, condition, **kwargs).rewrite(Expectation)
  527. def _eval_rewrite_as_Probability(self, X, n, condition=None, **kwargs):
  528. return self.rewrite(Expectation).rewrite(Probability)
  529. def _eval_rewrite_as_Integral(self, X, n, condition=None, **kwargs):
  530. return self.rewrite(Expectation).rewrite(Integral)