Random Composite Types
The mechanism for RandVars whose rangetype is some arbitrary Julia type, needs to be fleshed out. This, surprisingly, hasn't been much of an issue before because we could just use normal types, whose composite elements where RandVars, e.g.;
immutable Point
x::RandVar{Real}
y::RandVar{Real}
end
But this breaks down easily, I would like to be able to do something like
P = RandVar{Point}(normal(0,1),normal(0,1))
rand(P,P.x + Y.y > 0)
Additionally the need for this becomes clear when random variables interact with non random variables. Currently, Sigma supports properly supports things like
X = normal(0,1)
Y = X + 10 # Y is a random variable
But what about
a = [1,2,3,4,5]
X = discreteuniform(1,4)
Y = a[X]
Y of course, should be a random variable
One proposal for the latter case is something this:
immutable RandVarChoice{T} <: RandVar{T}
base::Array{T}
I::RandVar #The Random Index
end
getindex{T<:RandVar{Int}}(A::Array, i0::T) = RandVarChoice(A, i0)
call(X::RandVarChoice,ω) = X.base[call(X.I,ω)]
# Functions originally defined on base type, e..g
function (==){T}(X::RandVarChoice{T}, Y::RandVarChoice{T})
RandVarSymbolic{Bool}(:(call($X,ω) == call($Y,ω)))
end
The problems with this approach are
- A RandVarChoice can't in many ways be used as an element of the base type. We can't for instance, extract a property using the dot notation
- Consider these two different scenarios
normal_points = [Point(i,-i) for i = 1:10]
rand_points = [RandVar{Point}(Point(normal(i,1),normal(-i,1)) for i =1:10]
rand_index = discreteuniform(1,10)
# What are these?
normal_points[rand_index].x + normal_points[rand_index].y #1
normal_points[rand_index] == normal_points[rand_index] #2
rand_points[1].x + rand_points[2].y #3
rand_points[rand_index].x + rand_points[rand_index].y #4
- When we index the normal array with a random index, as in our proposal, we get back this
RandVarChoice. But then we try to access propertiesxandyfrom it, which is invalid. One solution is to use agetmethod
get(normal_points[rand_index],:x)
But then I've lost compatibility with a lot of existing code.
- Why should functions of
RandVarChocee.g.(==)evaluate toRandVarSymbolics. What should it be? - The result of
#1and of#3should both be Real valued random variables, but for different reasons. The latter because the propertiesxandyand themselves real random variables, and the former because the Point itself is randomly chosen, even thoughxandyare just normalReals.#4has both of these kinds of randomness.
For #3 once a bit of random is chosen, we have a Point. Hence the addition should be a RandVar which given some random input, creates the Point or set of, and does the addition on the point Points or sets of Points. This seems to fall under RandVarSymbolic but i) We cannot overload fields and so we will have the parameter problem RandVarSymbolic ii) What about use with the solver? Is all our work there, and with RandVarMeta redundant? iii) RandVarSymbolic currently has representation compactness issues, can we fix these.
concrete proposal:
- Automatically
lifta type into its random variable type. This could be done with a macro which inspects the fields and dynamically generates a new type. - Have these types be some kind of RandVarSymoblic.
- Fix the issues with RandVarSymbolic and reconsider whether RandVarSMT is necessary.