Open nabriis opened 1 year ago
Thank you for the thorough overview and suggestions based on our recent discussions.
Some questions to consider:
Would it be beneficial to have separate classes, e.g., simple rv and transformed rv, and how should they be related? If their behaviour is slightly different, eg, simple rv has the logd method, but transformed doesn't, that suggests separate classes to me, maybe simple subclassed from the more general transformed rv, adding the logd method?
Evaluation of expressions like z = x + 2*y
, is stated to have z(10)
return 10
. What is the motivation for that? Seems to assume y
is set to zero to get that. Would seem more intuitive to me to return another rv only depending on y
, perhaps with the x
node being in "evaluated rv, set to 10" mode somehow.
Accessing the underlying distribution for transformed variable like z
that depends on two rvs doesn't seem possible? Even for w=2*x
or w=x+1
we wouldn't immediately have the distribution of w
even if we have it of x
? So perhaps only simple rvs have distribution?
Conditioning in our original distribution sense and computing evaluating a transformed rv given the value of rvs it depends on still seem very similar to me. I would like to understand better whether there is absolutely a need for separate syntax. For example y = Gaussian(0, x)
as in the example above. Can't we interpret x
as an rv, so that y
is somehow a transformed rv, though not through simple algebraic combinations on x
. While the value of y
does have an additional layer of randomness since it is a distribution, we still essentially by y(x=10)
mean "give me y with x fixed at 10".
This issue builds upon discussion from #243.
This is a suggestion to streamline and make more user friendly the user interface of CUQIpy by creating a random variable when the user writes code like:
Instead of creating an instance of Distribution, the proposal is to change the
__new__
method of Distribution to actually return an instance of aRandomVariable
. This can be done via the following change to Distribution:Changes to user interface
High-level interface
By default random variables are created making the user interface follow the mathematical notation more closely:
$$ \begin{aligned} d &\sim \mathrm{Gamma}(1, 10^{-4})\ x &\sim \mathrm{Gaussian}(0,d^{-1})\ y &\sim \mathrm{Gaussian}(A(x), 1) \end{aligned} $$
in CUQIpy:
The random variables can then be passed as input to create a
BayesianProblem
or toJointDistribution
.Low-level interface
At a lower level the Random Variable contains the distribution inside of it. Certain "main properties" are exposed such as
The underlying distribution can be accessed to get more information e.g.
Certain methods exists for acting on random variables. These are:
Conditioning
Evaluation
Algebra
Algebra as shown in #243 works on RVs
Changes to underlying framework
The main change is to have distribution
__new__
method return aRandomVariable
. In addition we have to update many demos etc, that work directly with distributions to extract the distribution from the initialized random variable.Changes to name
.name
is currently used by distributions to keep track of the defined name of the distribution. This is used byJointDistribution
,Samplers
and in various other areas. This should be updated such that.name
is part ofRandomVariable
and in turn a hidden._name
method to get name can be stored in distributions at initialization time if that makes it simpler for the code.Changes to how conditioning looks for the user
We have to decide what to show the user when conditioning. Currently we have
Now (suggested)
One suggestion is to return a
RandomVariable
or maybe define/call itobserved RandomVariable
where the data and distribution is stored, perhaps via our current Likelihood class.Final point is if we fully condition a random variable. Then we end up in the situtation similar to the
EvaluatedDensity
. Thus do we need aEvaluatedRandomVariable
?