Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semantics of ciid #120

Closed
zenna opened this issue Oct 7, 2019 · 0 comments
Closed

Semantics of ciid #120

zenna opened this issue Oct 7, 2019 · 0 comments

Comments

@zenna
Copy link
Owner

zenna commented Oct 7, 2019

One of the issues is the semantics of rv.

Currently we have the slightly confusing behaviour

g = ciid(w -> rand(w))
h(w) = rand(w)

function f(w)
  x1 = g(w)
  x2 = g(w)
  y1 = h(w)
  y2 = h(w)
end

While x1 and x2 are the same, y1 and y2 are different.
The reason is that g is a random variable and h is simply a function of omega. There is a distinction between the two in Omega. In particular, random variables have the projection mechanism.

It's (arguably) confusing because you can't tell from the syntax that there are two different kinds of things. And it's confusing because if h(w) is simply function application then why are y1 and y2 different?

There is some degree to which we try to maintain compatibility with existing julia code, but let's ignore that for the moment and consider how it should be designed.

One proposal is as follows

g(w) = unif(w)
h(w) = unif(w)

function f(w)
  x1 = g(w)
  x2 = g(w)
  y1 = h(w)
  y2 = ciid(h)(w)
end

Here, we:

  • Get rid of rand(w) or w[1] and assume the existence of a set of primitive random variables. Actually all we need is a primitive unif(w)
  • ~ is a unary operator, so that ciid(x) returns a random variable that is distributed identially to x but conditionally independent given its parents.

This raises two issues:

  1. How can we specify ciid(x) rigorously. Either we can do so declaratively, then we need to formalize some notion of parent, or constructively, by giving the functional definition of the random variable.
  2. How can we ensure that ciid(h) is stable, i.e. that ciid is just a "pure" function. Currently we kind of informally say you shouldn't use ciid within a random variable because of its stateful behaviour (incrementing ids). This isn't good.

Let's assume we are more explicit, ciid(x, id) gives an explicit id and hence ciid is a pure function.

g(w) = unif(w)
h(w) = unif(w)

function f(w)
  x1 = g(w)
  x2 = g(w)
  y1 = h(w)
  y2 = ciid(h, 1)(w)
end

We can interpret ciid(h, 1) as being the 1st element in the class of random variables that are ciid to h. However, this is still problematic because what's to say this won't conflict with other code/random variables that f is unaware of. For example:

a(w) = ciid(unif, 1)(w)
b(w) = ciid(unif, 1)(w)

I wanted in a and b to get two independent uniform draws but instead I got the same thing by accident. For cleaner notation I'll use ~₂x to dneote ciid(x,2)

Suppose then we do the following.

a(w) = ~₁unif(w) + 2
h(w) = ~₁a(w)
g(w) = ~₂a(w)

What does ~₁a mean. If we took the current interpretation of the projection then h and g would be identical, due to the projection in ~₁unif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant