Calculating variance of a simple expression with sympy random variables - random

Two U(0,1) random variables, X1 and X2, and I want the variance of max(2,X1)+X2.
And I want it using sympy. Yes, I know it's too easy. However, I would like to know if there are built-in ways of handling problems like this one, and how to use them.
>>> from sympy.stats import Uniform, Variance
>>> from sympy import symbols, Integral
>>> X1 = Uniform('X1', 0, 1)
>>> X2 = Uniform('X2', 0, 1)
sympy seems to dislike max; it expresses the same distaste for the if statement.
>>> Variance(max(2, X1) + X2)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\Python34\lib\site-packages\sympy-1.0.1.dev0-py3.4.egg\sympy\core\relational.py", line 195, in __nonzero__
raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational
The problem is trivial, though, and I could simplify it sufficiently.
>>> Variance(2 + X2)
Variance(X2 + 2)
>>> Variance(2 + X2).evaluate_integral()
1/12
I am usually pretty thick unfortunately. How would I handle probability calculations involving conditionals?

Python's max doesn't work with SymPy objects; use SymPy's Max instead. Also, you don't need to use passive (un-evaluated) form Variance and then ask for its evaluation: just use variance which attempts evaluation. Example:
from sympy.stats import Uniform, variance, E
from sympy import Max
X1 = Uniform('X1', 0, 1)
X2 = Uniform('X2', 0, 1)
X3 = Max(2, X1) + X2
print(E(X3))
print(variance(X3))
This sort of works, except the integrals seem too hard to be to be evaluated anyway, as they contain Max. This is the output.
1/2 + Integral(Max(2, X1), (X1, 0, 1))
2*Integral(Max(2, X1), (X1, 0))*Integral(Max(2, X1), (X1, 0, 1)) - 2*Integral(Max(2, X1), (X1, 1))*Integral(Max(2, X1), (X1, 0, 1)) - Integral(Max(2, X1)**2, (X1, 0)) + Integral(Max(2, X1)**2, (X1, 1)) + 1/12 + Integral(Max(2, X1), (X1, 0, 1))**2
Forcing a numeric answer works for expected value:
print(E(X3).evalf())
prints 2.5. The only way I found to get a numeric value for variance is by sampling - that is, ask SymPy to generate a sample of given size and take variance from there, subject to sampling errors of course.
print(variance(X3, numsamples=1e4))
prints 0.0839550029765917.

Related

How does the power function work

This is My First Logic Programming Language course so this is a really Dumb Question But I cannot for the life of me figure out how does this power predicate work I've tried making a search tree to trace it But I still cannot understand how is it working
mult(_ , 0 ,0).
mult(X , Y, Z):-
Y > 0,
Y1 is Y - 1,
mult(X,Y1,Z1),
Z is Z1 + X.
exp2(_ ,0 , 1).
exp2(X,Y,Z):-
Y > 0,
Y1 is Y - 1,
exp2(X , Y1 , Z1),
mult(X,Z1,Z).
I so far get that I'm going to call the exp2 predicate till I reach the point where the Y is going to be Zero then I'm going to start multiplying from there, but At the last call when it's at exp2(2 , 1 , Z) what is the Z value and how does the predicate work from there?
Thank you very much =)
EDIT: I'm really sorry for the Late reply I had some problems and couldn't access my PC
I'll walk through mult/3 in more detail here, but I'll leave exp2/3 to you as an exercise. It's similar..
As I mentioned in my comment, you want to read a Prolog predicate as a rule.
mult(_ , 0 ,0).
This rule says 0 is the result of multiplying anything (_) by 0. The variable _ is an anonymous variable, meaning it is not only a variable, but you don't care what its value is.
mult(X, Y, Z) :-
This says, Z is the result of multiplying X by Y if....
Y > 0,
Establish that Y is greater than 0.
Y1 is Y - 1,
And that Y1 has the value of Y minus 1.
mult(X, Y1, Z1),
And that Z1 is the result of multiplying X by Y1.
Z is Z1 + X.
And Z is the value of Z1 plus X.
Or reading the mult(X, Y, Z) rule altogether:
Z is the result of multiplying X by Y if Y is greater than 0, and Y1 is Y-1, and Z1 is the result of multiplying X by Y1, and Z is the result of adding Z1 to X.
Now digging a little deeper, you can see this is a recursive definition, as in the multiplication of two numbers is being defined by another multiplication. But what is being multiplied is important. Mathematically, it's using the fact that x * y is equal to x * (y - 1) + x. So it keeps reducing the second multiplicand by 1 and calling itself on the slightly reduced problem. When does this recursive reduction finally end? Well, as shown above, the second rule says Y must be greater than 0. If Y is 0, then the first rule, mult(_, 0, 0) applies and the recursion finally comes back with a 0.
If you are not sure how recursion works or are unfamiliar with it, I highly recommend Googling it to understand it. That is, indeed, a concept that applies to many computer languages. But you need to be careful about learning Prolog via comparison with other languages. Prolog is fundamentally different in it's behavior from procedural/imperative languages like Java, Python, C, C++, etc. It's best to get used to interpreting Prolog rules and facts as I have described above.
Say you want to compute 2^3 as assign result to R.
For that you will call exp2(2, 3, R).
It will recursively call exp2(2, 2, R1) and then exp2(2, 1, R2) and finally exp(2, 0, R3).
At this point exp(_, 0, 1) will match and R3 will be assigned to 1.
Then when call stack unfolds 1 will be multiplied by 2 three times.
In Java this logic would be encoded as follows. Execution would go pretty much the same route.
public static int Exp2(int X, int Y) {
if (Y == 0) { // exp2(_, 0, 1).
return 1;
}
if (Y > 0) { // Y > 0
int Y1 = Y - 1; // Y1 is Y - 1
int Z1 = Exp2(X, Y1); // exp2(X, Y1, Z1);
return X * Z1; // mult(X, Z1, Z).
}
return -1; // this should never happen.
}

How to make a prolog program return the value it computed

(I'm not sur if return is the right word to describe it, but that's the best one I could find.)
I am trying to write a small program in prolog that uses the function add to do multiplications. When I run add by itself or even when it is called by the function test the result is "Z = the sum" ex: if I run add(2,3,Z) it will display Z=5.
My problem is that I can't get it to do the same thing when I call mult. The only solution that I found is to use write, but that's not the same thing. I tried a lot of stuff but most of it wasn't even compiling and the rest didn't change anything. Does anybody know how I could make it do that ("Z = the product")? What would be the way to make it do that (return) for a program in general?
Thank You
add(X,Y,Z) :-
Z is X + Y.
mult(X,Y,Z1):-
multiply(X,Y,0).
multiply(_,0,_):-
write(0).
multiply(0,_,Z):-
write(Z).
multiply(X,Y,Z):-
X > 0,
add(Y,Z,Z1),
X1 is X - 1,
multiply(X1,Y,Z1).
multiply(X,Y,Z):-
Y < 0,
X1 is abs(X),
Y1 is abs(Y),
multiply(X1,Y1,Z).
multiply(X,Y,Z):-
Y1 is Y * -1,
add(Y1,Z,Z1),
X1 is X + 1,
multiply(X1,Y,Z1).
test(X,Y,Z1):-
add(X,Y,Z1).
I managed to get it working by adding a 4th parameter. I don't know if it is the right way to do it but it works.
mult(X,Y,Z):-
multiply(X,Y,0,Z).
multiply(_,0,_,Z):-
Z is 0.
multiply(0,_,Z1,Z):-
Z is Z1.
multiply(X,Y,Z1,Z):-
X > 0,
add(Y,Z1,Z2),
X1 is X - 1,
multiply(X1,Y,Z2,Z).
multiply(X,Y,Z1,Z):-
Y < 0,
X1 is abs(X),
Y1 is abs(Y),
multiply(X1,Y1,Z1,Z).
multiply(X,Y,Z1,Z):-
Y1 is Y * -1,
add(Y1,Z1,Z2),
X1 is X + 1,
multiply(X1,Y,Z2,Z).

how to calculate a quadratic equation that best fits a set of given data

I have a vector X of 20 real numbers and a vector Y of 20 real numbers.
I want to model them as
y = ax^2+bx + c
How to find the value of 'a' , 'b' and 'c'
and best fit quadratic equation.
Given Values
X = (x1,x2,...,x20)
Y = (y1,y2,...,y20)
i need a formula or procedure to find following values
a = ???
b = ???
c = ???
Thanks in advance.
Everything #Bartoss said is right, +1. I figured I just add a practical implementation here, without QR decomposition. You want to evaluate the values of a,b,c such that the distance between measured and fitted data is minimal. You can pick as measure
sum(ax^2+bx + c -y)^2)
where the sum is over the elements of vectors x,y.
Then, a minimum implies that the derivative of the quantity with respect to each of a,b,c is zero:
d (sum(ax^2+bx + c -y)^2) /da =0
d (sum(ax^2+bx + c -y)^2) /db =0
d (sum(ax^2+bx + c -y)^2) /dc =0
these equations are
2(sum(ax^2+bx + c -y)*x^2)=0
2(sum(ax^2+bx + c -y)*x) =0
2(sum(ax^2+bx + c -y)) =0
Dividing by 2, the above can be rewritten as
a*sum(x^4) +b*sum(x^3) + c*sum(x^2) =sum(y*x^2)
a*sum(x^3) +b*sum(x^2) + c*sum(x) =sum(y*x)
a*sum(x^2) +b*sum(x) + c*N =sum(y)
where N=20 in your case. A simple code in python showing how to do so follows.
from numpy import random, array
from scipy.linalg import solve
import matplotlib.pylab as plt
a, b, c = 6., 3., 4.
N = 20
x = random.rand((N))
y = a * x ** 2 + b * x + c
y += random.rand((20)) #add a bit of noise to make things more realistic
x4 = (x ** 4).sum()
x3 = (x ** 3).sum()
x2 = (x ** 2).sum()
M = array([[x4, x3, x2], [x3, x2, x.sum()], [x2, x.sum(), N]])
K = array([(y * x ** 2).sum(), (y * x).sum(), y.sum()])
A, B, C = solve(M, K)
print 'exact values ', a, b, c
print 'calculated values', A, B, C
fig, ax = plt.subplots()
ax.plot(x, y, 'b.', label='data')
ax.plot(x, A * x ** 2 + B * x + C, 'r.', label='estimate')
ax.legend()
plt.show()
A much faster way to implement solution is to use a nonlinear least squares algorithm. This will be faster to write, but not faster to run. Using the one provided by scipy,
from scipy.optimize import leastsq
def f(arg):
a,b,c=arg
return a*x**2+b*x+c-y
(A,B,C),_=leastsq(f,[1,1,1])#you must provide a first guess to start with in this case.
That is a linear least squares problem. I think the easiest method which gives accurate results is QR decomposition using Householder reflections. It is not something to be explained in a stackoverflow answer, but I hope you will find all that is needed with this links.
If you never heard about these before and don't know how it connects with you problem:
A = [[x1^2, x1, 1]; [x2^2, x2, 1]; ...]
Y = [y1; y2; ...]
Now you want to find v = [a; b; c] such that A*v is as close as possible to Y, which is exactly what least squares problem is all about.

Matematica. Residue integral

I just started to use Mathematica and wanted to try out if I got a result correct from a residue integral i made. I have two poles in the UHP, actually looking more complicated but I just wanted to see if Mathematica could to this. This is my code:
x1 = Iw;
x2 = 2 Iw;
Integrate [e^(Ixt)/((x - x1) (x - x2)), {x, -infinity, infinity}, Assumptions -> t > 0]
Is this integral possible to do in Mathematica?
Mathematica sees Iw as a two character variable name, but I w as the product of two things.
Mathematica is fanatic about correct capitalization and spelling.
x1=I w; x2=2 I w;
Integrate[E^(I x t)/((x-x1)(x-x2)), {x,-Infinity,Infinity}, Assumptions-> t>0]
returns a large complicated result depending on the signs and whether w might be zero. If you can supply additional domain information the result might be simplified.

Given an increasing polynomial, how do you efficiently find x values for fixed intervals of y?

Problem: Given a polynomial of degree n (with coefficients a0 through an-1) that is guaranteed to be increasing from x = 0 to xmax, what is the most efficient algorithm to find the first m points with equally-spaced y values (i.e. yi - yi-1 == c, for all i)?
Example: If I want the spacing to be c = 1, and my polynomial is f(x) = x^2, then the first three points would be at y=1 (x=1), y=2 (x~=1.4142), and y=3 (x~=1.7321).
I'm not sure if it will be significant, but my specific problem involves the cube of a polynomial with given coefficients. My intuition tells me that the most efficient solution should be the same, but I'm not sure.
I'm encountering this working through the problems in the ACM's problem set for the 2012 World Finals (problem B), so this is mostly because I'm curious.
Edit: I'm not sure if this should go on the Math SE?
You can find an X for a given Y using a binary search. It's logarithmic time complexity, proportional to the size of the range of x values, divided by your error tolerance.
def solveForX(polyFunc, minX, maxX, y, epsilon):
midX = (minX + maxX) / 2.0
if abs(polyFunc(midX) - y) < epsilon:
return midX
if polyFunc(midX) > y:
return solveForX(polyFunc, minX, midX, y, epsilon)
else:
return solveForX(polyFunc, midX, maxX, y, epsilon)
print solveForX(lambda x: x*x, 0, 100, 2, 0.01)
output:
1.416015625
Edit: to expand on an idea in the comments, if you know you will be searching for multiple X values, it's possible to narrow down the [minX, maxX] search range.
def solveForManyXs(polyFunc, minX, maxX, ys, epsilon):
if len(ys) == 0:
return []
midIdx = len(ys) / 2
midY = ys[midIdx]
midX = solveForX(polyFunc, minX, maxX, midY, epsilon)
lowYs = ys[:midIdx]
highYs = ys[midIdx+1:]
return solveForManyXs(polyFunc, minX, midX, lowYs, epsilon) + \
[midX] + \
solveForManyXs(polyFunc, midX, maxX, highYs, epsilon)
ys = [1, 2, 3]
print solveForManyXs(lambda x: x*x, 0, 100, ys, 0.01)
output:
[1.0000884532928467, 1.41448974609375, 1.7318960977718234]

Resources