HollowDCBeam shape samples positions incorrectly
Positions should be distributed homogeneously however at the moment they are sampled as follows:
\begin{aligned}
r &= uniform(R_{min}, R_{max}) \\
\varphi &= uniform(0, 2\pi) \\
x &= r\cos(\varphi) \\
y &= r\sin(\varphi)
\end{aligned}
Because the arc length increases proportional to r
this leads to a distribution which decreases as 1/r
.
Solution
For sampling in polar coordinates the variable r
(radius) should follow a linearly increasing probability density function (PDF) with the following requirement:
\frac{p(r)}{p(R_{min})} = \frac{r}{R_{min}}
This criterion is met by the following PDF:
p(r) = m\cdot r \;, \; R_{min} \leq r \leq R_{max}
The cumulative distribution function is
F(r) = \int^{r}_{R_{min}}p(r')dr' = \frac{m}{2}r^2 - \frac{m}{2}R_{min}^2
Normalization to F(R_{max}) = 1
yields
m = \frac{2}{R_{max}^2 - R_{min}^2}
Using inverse transform sampling one arrives at
r = \sqrt{R_{min}^2 + u\cdot \left(R_{max}^2 - R_{min}^2\right)}
where u
is a uniform random variable on [0, 1]
. This is equivalent to r = \sqrt{\tilde{u}}
where \tilde{u}
is a uniform random variable on [R_{min}^2, R_{max}^2]
.
Therefore the radii can be sampled as follows:
radius = numpy.sqrt(
numpy.random.uniform(
self._inner_radius**2,
self._outer_radius**2,
size=count
)
)
\varphi
remains uniform on [0, 2\pi]
:
phi = numpy.random.uniform(0, 2*numpy.pi, size=count)