In sympy, how can I define two random variables, X and Y, that depend on a common condition? For example, how do I solve a problem such as the following:
We throw a dice. If it falls on 1, then X=1 and Y=0. If it falls on 2, then X=0 and Y=1. Otherwise, X=Y=0. What is the covariance of X,Y?
If X and Y are functions of some Z, then create Z and define X, Y through it. Piecewise helps with this:
from sympy.stats import *
Z = Die("Z", 6)
X = Piecewise((1, Eq(Z, 1)), (0, True))
Y = Piecewise((1, Eq(Z, 2)), (0, True))
print(covariance(X, Y)) # -1/36
Aside: If Y is a function of X, then create X first and then define Y in terms of it.
from sympy.stats import Bernoulli, covariance
X = Bernoulli("X", 1/6)
Y = 1 - X
print(covariance(X, Y))
Returns -0.138888888888889.
Related
To assert all elements of a list equal, is there no "Equal()" in z3py? There is for example Distinct().
Using numpy works:
from z3 import *
import numpy as np
s = Solver()
B = [BitVec(f"b{j}", 7) for j in range(11)]
C_eq = [B[i] == B[j] for i in range(3) for j in range(3) if i != j]
s.add(C_eq)
print(s.check())
print(s.model())
Indeed z3py supports Distinct, but not Equals. The reason is that a straightforward encoding of Distinct requires quadratic number of constraints, and it can bog the solver down. Having a Distinct primitive allows the solver to avoid this bottleneck. Equals, however, only requires a linear number of constraints in the number of variables and typically doesn't need any special help to be efficient.
To simplify your programming, you can define it yourself, however. Something like this:
from z3 import *
def Equals(*xs):
constr = True
if xs:
base = xs[0]
for x in xs[1:]:
constr = And(constr, base == x)
return constr
And then use it like this:
x, y, z = Ints('x y z')
print(Equals())
print(Equals(x))
print(Equals(x, y))
print(Equals(x, y, z))
which prints:
True
True
And(True, x == y)
And(And(True, x == y), x == z)
I've been given the following function written in pseudocode:
P:
{
int x, y, z;
read (x, y, z);
while (x != y) {
x = x - y;
z = z + y
};
write z;
}
Given that f(x,y,z) is the function calculated by P, I would like to know if the function "g(x,y,z)=1 if f(x,y,z) is not a total function or g(x,y,z)=0 otherwise", is computable.
My first guess is: yes, it is computable (for example for x=y).
Is there a more rigorous general approach to prove that?
P does not change the value of y, and the only way it changes the value of x is to subtract y from x until x = y. If subtracting y from x does not eventually result in x = y, then the loop continues forever. We know that subtracting y from x repeatedly can only cause x = y if initially x = cy for natural numbers c >= 1. So, g(x,y,z) = 1 because f(x,y,z) is not a total function; it is undefined when x != cy for any natural number c >= 1. Even if what you meant is that g(x,y,z) = 1 whenever f(x,y,z) is defined, it is still computable, since g(x,y,z) is the function:
g(x,y,z) = { 1, if x = cy for some natural number c >= 1 }
{ 0, otherwise }
The condition x = cy for some natural number c >= 1 is itself computable since this is equivalent to "x >= y" and "GCD(x, y) = y".
I have:
:-use_module(library(clpr)).
comp(X, Y, Z):-
{X = Y * Z, Y = Z, Y > 0, Z > 0}.
Which with the query:
?-comp(X,3,Z).
Yields:
X = 9.0,
Z = 3.0
as expected. But why doesn't
comp(9,Y,Z).
also give me values for Y and Z? What I get is instead:
{Z>0.0,Y=Z,9-Y*Z=0.0},
{9-Y*Z=0.0},
{9-Y*Z=0.0}
Thanks!
Probably a weakness of the used CLP(R) that quadratic case doesn't work so well. After Y = Z, it is evident that X = Y**2, and then with X = 9 and Y > 0, you should easily get Y = 3. Which CLP(R) do you use?
A CLP(R) need not only support linear equalities and inequalities. Using for example Gröbner Basis algorithm a CLP(R) could do more, even algebraically. Some computer algebra system can do that easily.
So I guess its not a problem of Prolog per se, rather of the library. Strictly speaking CLP(X) only indicates a domain X. For the domain R of real numbers there is wide variety of potential equation and inequation solvers.
Better with constraints over finite domains using this module:
:-use_module(library(clpfd)).
comp(X, Y, Z):-
X #= Y * Z, Y #= Z, Y #> 0, Z #> 0.
With
comp(9,Y,Z).
I get:
Y = Z, Z = 3
I have defined a function f(x, y, z) in Julia and I want to parallely compute f for many values of x, holding y and z fixed. What is the "best practices" way to do this using pmap?
It would be nice if it was something like pmap(f, x, y = 5, z = 8), which is how the apply family handles fixed arguments in R, but it doesn't appear to be as simple as that. I have devised solutions, but I find them inelegant and I doubt that they will generalize nicely for my purposes.
I can wrap f in a function g where g(x) = f(x, y = 5, z = 8). Then I simply call pmap(g, x). This is less parsimonious than I would like.
I can set 5 and 8 as default values for y and z when f is defined and then call pmap(f, x). This makes me uncomfortable in the case where I want to fix y at the value of some variable a, where a has (for good reason) not been defined at the time that f is defined, but will be by the time f is called. It works, but it kind of spooks me.
A good solution, which turns your apparently inflexible first option into a flexible one, is to use an anonymous function, e.g.
g(y, z) = x -> f(x, y, z)
pmap(g(5, 8), x)
or just
pmap(x -> f(x, 5, 8), x)
In Julia 0.4, anonymous functions have a performance penalty, but this will be gone in 0.5.
This is a follow up question for: Subtraction operation using only increment, loop, assign, zero
We're only allowed to use the following operations:
incr(x) - Once this function is called it will assign x + 1 to x
assign(x, y) - This function will assign the value of y to x (x = y)
zero(x) - This function will assign 0 to x (x = 0)
loop X { } - operations written within brackets will be executed X times
For example, addition can be implemented as follows:
add(x, y) {
loop x
{ y = incr(y) }
return y
}
How do I implement the relational operators using these four operations? The relational operations are:
eq(x, y) - Is x equal to y?
lt(x, y) - Is x lesser than y?
gt(x, y) - Is x greater than y?
We also have their opposites:
ne(x, y) - Is x not equal to y?
gte(x, y) - Is x greater than or equal to y?
lte(x, y) - Is x lesser than or equal to y?
Any help will be appreciated.
The set of natural numbers N is closed under addition and subtraction:
N + N = N
N - N = N
This means that the addition or subtraction of two natural numbers is also a natural number (considering 0 - 1 is 0 and not -1, we can't have negative natural numbers).
However, the set of natural numbers N is not closed under relational operations:
N < N = {0, 1}
N > N = {0, 1}
This means that the result of comparing two natural numbers is either truthfulness (i.e. 1) or falsehood (i.e. 0).
So, we treat the set of booleans (i.e. {0, 1}) as a restricted set of the natural numbers (i.e. N).
false = 0
true = incr(false)
The first question we must answer is “how do we encode if statements so that we may branch based on either truthfulness or falsehood?” The answer is simple, we use the loop operation:
isZero(x) {
y = true
loop x { y = false }
return y
}
If the loop condition is true (i.e. 1) then the loop executes exactly once. If the loop condition is false (i.e. 0) then the loop doesn't execute. We can use this to write branching code.
So, how do we define the relational operations? Turns out, everything can be defined in terms of lte:
lte(x, y) {
z = sub(x, y)
z = isZero(z)
return z
}
We know that x ≥ y is the same as y ≤ x. Therefore:
gte(x, y) {
z = lte(y, x)
return z
}
We know that if x > y is true then x ≤ y is false. Therefore:
gt(x, y) {
z = lte(x, y)
z = not(z)
return z
}
We know that x < y is the same as y > x. Therefore:
lt(x, y) {
z = gt(y, x)
return z
}
We know that if x ≤ y and y ≤ x then x = y. Therefore:
eq(x, y) {
l = lte(x, y)
r = lte(y, x)
z = and(l, r)
return z
}
Finally, we know that if x = y is true then x ≠ y is false. Therefore:
ne(x, y) {
z = eq(x, y)
z = not(z)
return z
}
Now, all we need to do is define the following functions:
The sub function is defined as follows:
sub(x, y) {
loop y
{ x = decr(x) }
return x
}
decr(x) {
y = 0
z = 0
loop x {
y = z
z = incr(z)
}
return y
}
The not function is the same as the isZero function:
not(x) {
y = isZero(x)
return y
}
The and function is the same as the mul function:
and(x, y) {
z = mul(x, y)
return z
}
mul(x, y) {
z = 0
loop x { z = add(y, z) }
return z
}
add(x, y) {
loop x
{ y = incr(y) }
return y
}
That's all you need. Hope that helps.