Your assignment turn in will consist of a write up along with code pushed to Gitlab.
The purpose of this assignment is to get you a bit of practical experience in writing code for handling probability distributions, and to give you some idea of the potential power that comes from techniques like importance sampling.
Difficulty Cliffs - Gilbert tried doing a lot of different questions. Some of those questions didn't work out. Others ended up being way too hard for the time available. This assignment has been slimmed down as a result.
Update your GitLab repository fork of CaCL. Congratulations!
Check out the new cacl/distributions.py file. This file is set up in a way similar to cacl/builtins.py. It defines a number of built-in distributions that the user can sample from. In this problem (and in another problem!) we will write a new distribution.
For this problem, you should implement the poorly named subsquare distribution. This distribution is defined over the built in type Square (see cacl/types.py) which is defined by the position of the bottom-left corner, and the side length of the square. The distribution you implement should satisfy the following properties (which uniquely define it)
All generated squares should lie within the unit square [0,1]x[0,1].
The probability of generating a square should be proportional to its area.
The probability of generating any particular valid square of a given area should be uniform.
While there is relatively little code required for this problem (you don't even need to implement the PPL features!) you will need to think critically about how to achieve the above properties. Recall the basic sampling tricks we learned. You will also need to correctly implement a density function for this distribution. NOTE: The provided test is not complete of all required behavior, so do not solely rely on it to know whether you've successfully completed the problem.
In this problem you will implement support for a few new PPL features in the cacl/interpreter.py file. You can find the spots where implementation is required by looking for NotImplementedErrors being raised.
Not all of the features are properly tested. You should still seek to implement both rejection and score-based execution procedures. Observe that these are initiated by the new top-level command estimate. Most of the constituitive code has already been written, so you should be able to focus on the few key spots in the code.
In this last problem you are being asked to design a useful importance sampling routine.
When writing raytracers and other rendering systems, one often needs to sample a ray travelling in a random direction. Often, this ray will make no contribution to an integral unless it hits a light-source. Importance sampling is crucial in these application cases. A light bulb at the other end of a room may cast a considerable amount of light despite only occupying a tiny fraction of the total field of view from some point.
In this problem, you are asked to estimate the fraction of rays shot randomly from the origin which hit a small cube in the distance. Because the cube is being viewed at an angle and due to the spherical projection involved, it is far from trivial to analytically compute this integral. On the other hand, naive Monte Carlo will not succeed. The estimated fraction of the sphere's area subtended by the cube is around 1.0e-4. So, you will need to do importance sampling.
Your task in this problem involves a few steps:
First, using test_cube_light_estimator_variance, estimate the answer for a cube with side-lengths of 2.0. Make sure to use enough samples.
Estimate the variance of your estimator. How bad is it? What is the correct way to get this number?
Implement a new distribution called importance_sphere. Be creative! There are many spherical distributions you can lookup online. Or you could invent your own. Make sure you can direct this distribution towards the target object. If you use Wikipedia or other online resources for suggestions, (which I encourage!) please just make sure to give credit to your sources.
Estimate the variance of this new estimator for side-lengths of 2.0 as well as the original 0.5. How much better does importance sampling work?