probcomp / Venturecxx

Primary implementation of the Venture probabilistic programming system
http://probcomp.csail.mit.edu/venture/
GNU General Public License v3.0
28 stars 6 forks source link

Implement log_density_at #525

Open fsaad opened 8 years ago

fsaad commented 8 years ago

Following on https://github.com/probcomp/Venturecxx/issues/197. Letting x be the variables in (scope, block), q are x parents, and c are the children, we have:

To complete the symmetry, we require something which computes p(x|q)

The easiest way to implement this is through the identity:

(log_density_at scope block)
   = (- (log_joint_at scope block) (log_likelihood_at scope block))

except you can't subtract VentureRecords, but the idea is clear.

I wrote simple programs that verify the current software does the right thing (that log_joint minus log_likelihood is equal to a manually computed log_density) and I will convert them into Venture tests for the test suite in the near future. It might fail in more complex cases though which I do not know about.

Aside: I think that log_likelihood is a good name since it computes probability of the children c given the nodes x, i.e. L(x) = p(c|x), and does not claim to be a density anyway in its name. We might want to emphasize that log_joint_at is a density as well.

axch commented 8 years ago

The functionality as specified can be implemented easily with an addition to the inference prelude, along the lines of

(lambda (scope block)
  (do (joint <- (log_joint_at scope block))
      (likelihood <- (log_likelihood_at scope block))
      (return (- joint likelihood))))

However, semantically speaking, that would be needlessly sensitive to

It should be possible to obtain the same feature by just a detach-regen cycle on a funny scaffold whose absorbing border were exactly x and which had no principal nodes.

It should also be possible to obtain this feature by a detach-regen cycle an a (different) funny scaffold with principal nodes x and a hard stop without finding any absorbing border. The hard stop is safe because the values of x are not being changed; the actual number would be computed by making a "proposal" to deterministically set x to the values it currently has, with DeterministicLKernel.

Opinions on which path to take? One expedient would be to add the compound definition and file the primitive one as a separate performance and robustness improvement ticket. @fsaad , did you say you had unit tests?

lenaqr commented 8 years ago

It should be possible to obtain the same feature by just a detach-regen cycle on a funny scaffold whose absorbing border were exactly x and which had no principal nodes.

Does this actually work in the case where x contains multiple exchangeably-coupled applications?

axch commented 8 years ago

Should. Detach should unincorporate and regen reincorporate properly.

axch commented 8 years ago

Also part of #570.

axch commented 8 years ago

crashes from log_joint_at (#211) now fixed.

fsaad commented 8 years ago

Marking as important for PPAML, for logpdf of cgpms.

axch commented 8 years ago

Does that label reflect well what you meant?

fsaad commented 8 years ago

Sounds right, as impeding is weaker than blocking. [[Edit: Or is it not?]]]