# Void data

For a compilation of a lot of data relevant for working with the void-galaxy cross-correlation function see this page.

# Comparison to theory model (Realspace Voids)

For this test we use the true outflow velocity measured in the simulations (i.e. we assume we know $v_r(r)$ perfectly) and with realspace voids. This is then just testing the realspace-redshiftspace mapping (+ the streaming model) works well. In all the plots below we show $\xi_0,\xi_2,\xi_4$. My implementation of the theory model can be found here. For an example of how to use it on the database above see e.g. here. The Victor code is the one presently on github. The only modifications we have done is to removed the stochastic component in the Jacobian for the "dispersion" model (though we mainly use the "streaming" model in the tests below).

### VIDE with circumcenter

#### With multipoles in theory model (left) and without (right)

The results of having the full reconstruction $\xi_r(r,\mu)$ in the theory model is almost identical to $\xi_r(r)$. This is not surprising since with both voids and halos in realspace we should have $\xi_r(r,\mu) = \xi_0(r)$ unless there is some systematical errors in the void-finding that introduces anisotopies (which is very unlikely).

# Comparison to theory model (Reconstruction Voids)

For this test we provide it with the true outflow velocity measured in the simulations. But we now use reconstruction with a smoothing scale $R=7.5$ Mpc$/h$ to locate voids (so this case is close to what we would do in observations). This is the optimal value for the smoothing scale - (he one that minimizes the quadrupole of the post-recon halo auto power-spectra.

### Spherical

#### With multipoles in theory model (left) and without (right)

Here we see some small advantage of using the full reconstruction $\xi_r(r,\mu)$ in the theory model and not just the radial one $\xi_r(r)$. This is espesially try for the hexadecapole. We provide further tests of this below (see Reconstruction with non-optimal smoothing scale) which will show more clearly that "with" is always better.

# Comparison to theory model (Reconstruction Voids with too small reconscale)

When we use reconstruction with a smoothing scale that is not optimal, $R=5.0$ Mpc$/h$ instead of the optimal $R=7.5$ Mpc$/h$, then we induce higher order multipoles in the reconstructed $\xi_r(r,\mu)$. Here we test how the theory model works when we include the full $\xi_r(r,\mu)$ instead of just the radial one $\xi_r(r)$ in the theory model. For this test we use the true outflow velocity measured in the simulations (i.e. we assume we know $v_r(r)$ perfectly).

### Voxel with circumcenter

#### With multipoles in theory model (left) and without (right)

Here we really see the advantage of using the full reconstruction $\xi_r(r,\mu)$ in the theory model and not just the radial one $\xi_r(r)$.

# Comparison to theory model (Reconstruction Voids with too high reconscale)

When we use reconstruction with a smoothing scale that is not optimal, $R=10.0$ Mpc$/h$ instead of the optimal $R=7.5$ Mpc$/h$, then we induce higher order multipoles in the reconstructed $\xi_r(r,\mu)$. Here we test how the theory model works when we include the full $\xi_r(r,\mu)$ instead of just the radial one $\xi_r(r)$ in the theory model. For this test we use the true outflow velocity measured in the simulations (i.e. we assume we know $v_r(r)$ perfectly).

### Voxel with circumcenter

#### With multipoles in theory model (left) and without (right)

Again we see that using the full reconstruction $\xi_r(r,\mu)$ in the theory model instead of just the radial one $\xi_r(r)$ is always better. However we don't get as good results as above. One reason could be related to the fact that the larger the reconstruction scale is the more information we are "washing out" with the smoothing.

# Redshiftspace to realspace mapping with stochastic velocity component

The relation between redshiftspace and realspace coordinates is $$s_{||} = r_{||} + \frac{v_{||}}{aH},~~~s_\perp = r_\perp$$ where $v_{||}$ is the line of sight component of the outflow velocity. The velocity is modelled as a coherent radial out-flow from the void $v_r(r)$ (which we can model) together with a stochastic component vrandom along the line of sight $$\vec{v} = v_r(r)\hat{r} + v_{||~~\rm random}\hat{n}_{\rm LOS}$$ This gives us $$r_{||} = \frac{s_{||} - \frac{v_{||~~\rm random}}{aH}}{1 + \frac{v_r(r)}{raH}}$$ which we must solve in the theory model to get the real-space coordinates. This is an implicit equation for $r_{||}$ which we solve by iterating it a few times starting with $r = s$. Another way of dealing with the random component is to instead add it in realspace, i.e. we first compute $r_{||}$ above with $v_{||~~\rm random} = 0$ and then add the random component afterwards as $$r_{||}\to r_{||} - \frac{v_{||~~\rm random}}{aH}$$ This is how some implementations of the theory model has dealt with this. We here test which procedure is the better one: 1) the first method and 2) the second method (what we call "seperate" below).

### VIDE with circumcenter

#### Seperate (left) and together (right)

It is a small effect, but in all cases we see that doing it seperately gives worse results.

# Comparison to theory model (Exact velocity vs DM density template vs linear bias)

Here we compare using the exact velocity (the one measured in the simulations) to the linear theory relation $v_r(r) = -\frac{f}{3}(Hr)\Delta_{\rm DM}(r)$ where $\Delta_{\rm DM}(r)$ is the DM density profile measured in the simulations. We also test the linear bias approximation where $\Delta_{\rm DM}(r) = \frac{\Delta_{\rm halo}(r)}{b}$ is computed assumed as linear bias relation, where $b$ is computed from the auto power-spectra of halos, and $\Delta_{\rm halo}(r)$ is the halo density profile measured in the simulations. For this test we use realspace voids.

### VIDE with circumcenter

#### Exact Velocity (left), DM template (middle) and linear bias (right)

We find that the linear theory relation using the DM template works well for Zobov (circumcenter), Voxel (circumcenter) and Spherical. However it works worse for the barycenter definitions. Linear bias...

# Mean of theory vs theory of mean

In all the plots above we compute the theory and data predictions for each simulation and then take the mean in the end. We could also take the mean of the data in each simulation and then compute the theory prediction for this. The theory has a non-linear dependence on the input so its not automatic that they agree - and in some situations its convenient to do one or the other so its good to test this. A comparison of this is shown below.

### VIDE with circumcenter

#### Mean of theory (left) and theory of mean (right)

We find very consistent results between these two ways of analyzing the data.

# Code comparison (single realization)

Here I compare the results I get with my code with Victor (using the $\Delta_{\rm DM}$ template method for velocity) and also with the improved method of doing the redshiftspace-realspace mapping in one go and including higher order multipoles in the realspace correlation function. This is using a single realisation. The python script used to run Victor can be found here and the python script used to run my theory code (which itself can be found here) can be found here. For Victor we have used the streaming model. In my code we have used the dispersion model (with no random velocity in the Jacobian which then should is mathematically equivalent to the streaming model).

### Spherical

#### Victor (left), mine (middle), mine improved (right)

We find a good comparison with Victor. But there are some small discrepancies that are worth figuring out.

# Code comparison (all realizations)

Only one realization is noisy and the theory calculation will be sensitive to the interpolation methods etc. used. Therefore I also include a comparison of my code with Victor (exactly the same setup as above) where the template etc is computed as the mean from 100 realisation.

### Spherical

#### Victor (left), mine (middle), mine improved (right)

We also add a comparison when computing the theory prediction without taking the stocastic velocity into account ('Kaiser' in Victor; no-dispersion in mine):

### Spherical

#### Victor (left), mine (middle), mine improved (right)

We find a good comparison with Victor. But there are some small discrepancies that are worth figuring out. The small differences in "no-dispersion" probably from small differences in the way we do the coordinates shifts. The rest probably comes from the different ways we do the dispersion integral. Can also be differences related to use of smoothing filters, how things are splines etc, but so far this does not seem to cause any difference (tried doing it as similar as possible and no big change).

# Comparison of Streaming and Dispersion model in Victor

Victor has two options "dispersion" and "streaming". These are mathematically equivalent. Here we show how to implement them as to give identical results. For "dispersion" the correct way of doing the coordinate shift is $$r_{||} = \frac{s_{||} - \frac{v_{||}}{aH}}{1 + \frac{v_r(r)}{aHr}}$$ instead of $$r_{||} = \frac{s_{||}}{1 + \frac{v_r(r)}{aHr}} - \frac{v_{||}}{aH}$$ as it was implemented originally. Also the Jacobian should not have any contribution from the random velocity as it originally had.

        if settings['rsd_model'] == 'dispersion':  # implement the velocity dispersion model of Nadathur & Percival 2019

# Convert variable of integration from v to y=v/aH
sigma_y = sigma_v * rescaled_sv_norm_func(S) * self.iaH
y = sigma_y * Y

# Note: we integrate over the range [-X, X] where X = settings['yrange'] * sigma_y
r_par = (true_spar - y) / (1 + self.iaH * v_r_interp(true_s) / true_s)
for i in range(settings.get('niter', 5)):
r = np.sqrt(true_sperp**2 + r_par**2)
r_par = (true_spar - y) / (1 + self.iaH * v_r_interp(r) / r)
true_mu_r = r_par / r
true_mu_r[r == 0.0] = 0.0

# vr_term corresponds to v_r/raH where v_r is radial outflow plus component of random dispersion velocity
# vr_prime_term corresponds to 1/aH times derivative wrt r of v_r
vr_term = self.iaH * v_r_interp(r) / r
vr_prime_term = self.iaH * v_r_p_interp(r)
jacobian = (1 + vr_term + (vr_prime_term - vr_term) * true_mu_r**2)

# Velocity PDF
sy = sigma_v * rescaled_sv_norm_func(r) * self.iaH  # recalculate dispersion at each point
pdf = norm.pdf(y, loc=0.0, scale=sy)

# the resulting model prediction for xi(s, mu) from integration
integrand = (1 + rescaled_xi_r(r)) / jacobian * pdf
xi_smu = simps(integrand, x=y, axis=2) - 1


For the "streaming" option the implementation is as before:

        elif settings['rsd_model'] == 'streaming':  # implement a Gaussian streaming model

# in this case we recalculate r_par as the coherent mean value is not required
y = Y * sigma_v * rescaled_sv_norm_func(S) * self.iaH
r_par = true_spar - y

# iterate a few times to ensure convergence
for i in range(settings.get('niter', 5)):
r = np.sqrt(true_sperp**2 + r_par**2)
y = Y * sigma_v * rescaled_sv_norm_func(r) * self.iaH
r_par = true_spar - y
r = np.sqrt(true_sperp**2 + r_par**2)
true_mu_r = r_par / r
true_mu_r[r == 0.0] = 0.0

sv = sigma_v * rescaled_sv_norm_func(r)
v = Y * sv
vel_pdf = norm.pdf(v, loc=v_r_interp(r) * true_mu_r, scale=sv)
integrand = (1 + rescaled_xi_r(r)) * vel_pdf
xi_smu = simps(integrand, x=v, axis=2) - 1


Here we show the difference we get in the multipoles for the two options. They agree to an error of $10^{-6}$ which is more than good enough. Better agreement can be gotten by using a finer integration grid and/or using more points when evaluating the multipole integrals.