# How to get Simplified variance of a random variable?

**URL:** <https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071>\
**Category:** General Usage\
**Tags:** question, sympy, symbolic-utils\
**Created:** [February 23, 2023, 11:00am UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071 "2023-02-23T11:00:55Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [February 23, 2023, 11:00am UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071/1 "2023-02-23T11:00:55Z")

</div>

Hi all,

I want to use Julia to get the end result like this:  
 ![Capture d’écran_2023-02-23_17-57-29](https://global.discourse-cdn.com/julialang/original/3X/e/4/e425659e1c61255ea5f550b871871fcad7328e57.png)

the Expectation of (X - \mu)^{2} will be computed at the end to become:

E(X^{2}) - \mu^{2}

but how?

this is my try out:

```julia
using SymPy
# https://docs.sympy.org/latest/tutorials/intro-tutorial/simplification.html
@syms x, μ

v = expand((x-μ)^2)

function E(h)
	if h == x^2
	  return x^2
	elseif h==x*μ
	  return x*μ
	elseif h==μ^2
	  return μ^2
	end
end

```

what should I do next? I was thinking of creating a function with `if` and `ifelse`, maybe there is another way?

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [February 23, 2023, 2:27pm UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071/2 "2023-02-23T14:27:10Z")

</div>

Not sure if I understand what you want to do in the end:

- _Compute_ the variance of a random variable based on a sample? If you have a sample of the random variable X and want to know/estimate the variance, there would be tools for that in [Statistics · The Julia Language](https://docs.julialang.org/en/v1/stdlib/Statistics/) And probably lots more.
- _Compute_ the variance based on its distribution? Then perhaps [Distributions Package · Distributions.jl](https://juliastats.org/Distributions.jl/stable/) is more useful.
- (I guess this is what you want) _Represent_ random variables symbolically in a program? E.g. the operation \mathbb{E} which represents the mean of a random variable with the properties you described (e.g. \mathbb{E}(\mathbb{E}(X)) = \mathbb{E}(X) ). I’m not sure if there is a package that does this already, but it seems like sympy does have types that represent random variables – doesn’t seem like they have been ported to SymPy.jl yet though.

Here is an overview of what sympy can do  
[https://docs.sympy.org/latest/modules/stats.html](https://docs.sympy.org/latest/modules/stats.html)

If you just want to implement a “rewriting rule” that takes an expression like `E((x - mu)^2)` and returns `E(x^2) - mu^2` this might also be helpful: [SymbolicUtils.jl](https://symbolicutils.juliasymbolics.org/rewrite/)

Perhaps you could define a symbolic function `E` and specify some rewrite rules.

---

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [February 23, 2023, 3:05pm UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071/3 "2023-02-23T15:05:23Z")

</div>

Yes! I want to implement “rewriting rule”

but the `SymbolicUtils` package does not work, I tried it:  
 ![Capture d’écran_2023-02-23_22-03-34](https://global.discourse-cdn.com/julialang/original/3X/a/0/a01033e731f59951b412867dec36655c6f9c9e43.png)

Anyway, I want to try SymPy, thanks for pointing out it is `rewriting technique`… I just need to know the method or name.

In Probability and Statistics there are tons of this to prove E(X^{2}), etc…

---

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [February 23, 2023, 3:21pm UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071/4 "2023-02-23T15:21:14Z")

</div>

I try to use PyCall and SymPy:

```julia
using PyCall

ENV["PYTHON"] = "/home/browni/.julia/conda/3/bin/python3"
# the path is from the command 'which python3'

py"""
from sympy import symbols, Integral
from sympy.stats import Normal, Expectation, Variance, Probability

mu = symbols("μ", positive=True)

sigma = symbols("σ", positive=True)

#pdf = (15/512)*(x**2)*((4-x)**2)
X = Normal("X", mu, sigma)

print('Normal distribution')
print('Var(X) =',Variance(X).evaluate_integral())

print('E(X-μ) =',Expectation((X - mu)**2).expand())
print('final computation:')
print('E(X-μ) =',Expectation((X - mu)**2).doit())

"""

```

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [February 23, 2023, 4:02pm UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071/5 "2023-02-23T16:02:25Z")

</div>

Just to add to this excellent answer, you may need to import the `stats` module to use within `SymPy.jl`. Here are steps that should work for that:

```julia
import PyCall
PyCall.pyimport_conda("sympy.stats", "sympy")

```

Here is a sample usage:

```julia
Z = sympy.stats.Normal("Z", 0, 1)
sympy.stats.E((Z- 0)^2)

```

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [February 23, 2023, 8:11pm UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071/6 "2023-02-23T20:11:03Z")

</div>

> [@Freya\_the\_Goddess](#):
>
> but the `SymbolicUtils` package does not work, I tried it:

It should work. Did you start a new REPL session when trying the code?  
Both SymPy.jl and SymbolicUtils.jl export `@syms`, so what happened in your case is probably that `z` is a Sympy symbol and thus the rewriting does not work (it looks for SymbolicUtils symbols in the expression).

---

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [February 28, 2023, 5:14am UTC](https://discourse.julialang.org/t/how-to-get-simplified-variance-of-a-random-variable/95071/7 "2023-02-28T05:14:53Z")

</div>

it works after restarting REPL. Intersecting with SymPy is the problem. Thanks!
