Skip to content

Structure Function

structure_function

StructureFunction

Compute the second order structure function on a 2D binned map as \(\mathrm{SF}(s) = \frac{1}{N_p(s)} \sum_{d(\mathcal{W}_1, \mathcal{W}_2) = s} |C_{\mathcal{W}_1} - C_{\mathcal{W}_2}|^2\)

with \(\mathcal{W}_1, \mathcal{W}_2\) two separate regions, \(d\) the distance that separates them and \(N_p\) the number of pairs separated by \(s\).

Source code in src/xifu_cluster_sim/structure_function.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class StructureFunction:
    r"""
    Compute the second order structure function on a 2D binned map as
    $\mathrm{SF}(s) = \frac{1}{N_p(s)} \sum_{d(\mathcal{W}_1, \mathcal{W}_2) = s} |C_{\mathcal{W}_1} - C_{\mathcal{W}_2}|^2$

    with 
    $\mathcal{W}_1, \mathcal{W}_2$ two separate regions, $d$ the distance that separates them and $N_p$ the number of pairs separated by $s$.
    """

    def __init__(self,
                bins = np.geomspace(1,40,15)
                ):
        """
        Initialize

        Parameters:
            bins (np.array): Bins over which the structure function is computed, in units of pixels.
        """

        self.bins = bins

    def compute_from_vector(self,
                        binning,
                        v_bin_vec):
        """
        Computes the 2nd order structure function from a vector.
        This vector is taken from a binning, where the i-th value of the vector is the value in the i-th bin of the map.

        Parameters:
            binning (binning): Binning instance
            v_bin_vec (jnp.array): Array of the value in each bin


        Returns:
            bin_dists (jnp.array): Separations of the SF
            bin_means (jnp.array): Values of the SF
        """

        #Indexes of all possible combinations
        idx = jnp.triu_indices(len(binning.xBar_bins), k = 1)

        #Vector of all possible separations
        sep_vec = jnp.hypot(binning.xBar_bins[idx[0]] - binning.xBar_bins[idx[1]],
                            binning.yBar_bins[idx[0]] - binning.yBar_bins[idx[1]])

        #Vector of (v_i - v_j)^2 
        v_vec = (v_bin_vec[idx[0]] - v_bin_vec[idx[1]])**2

        ### PREVIOUS VERSION
        #Now compute binned statistics
        #Average SF in each bin
        #bin_means, bin_edges, binnumber = stats.binned_statistic(sep_vec, v_vec, 'mean', bins = self.bins)
        #Average distance in each bin
        #bin_dists, bin_edges, binnumber = stats.binned_statistic(sep_vec, sep_vec, 'mean', bins = self.bins)

        ### JAX VERSION
        hist_weighted, bin_edges = jnp.histogram(sep_vec, bins = self.bins, weights = v_vec)
        hist_numbers, bin_edges = jnp.histogram(sep_vec, bins = self.bins)
        hist_dists, _ = jnp.histogram(sep_vec, bins = self.bins, weights = sep_vec)

        #Average SF in each bin
        bin_means = hist_weighted/hist_numbers

        #Average distance in each bin
        hist_dists = hist_dists/hist_numbers


        #Note : in principle, we shouldn't be taking the average distance in each bin, we should
        #take the bin center, but that's for comparison purposes with Edo's code
        #For most cases, with a lot of values in each bin, the average is equivalent with the bin center.

        return hist_dists, bin_means

    def compute_from_map(self, binning, v_map):
        """
        Computes the 2nd order structure function of a binned image with arbitrary binning.

        Parameters:
            binning (binning): Binning instance
            v_bin_vec (jnp.array): Map of the binned values

        Returns:
            bin_dists (jnp.array): Separations of the SF
            bin_means (jnp.array): Values of the SF
        """

        v_bin_vec = jnp.ones(binning.nb_bins)
        v_bin_vec = v_bin_vec.at[binning.bin_num_pix].set(v_map[binning.X_pixels,
                                                                binning.Y_pixels])

        #Indexes of all possible combinations
        idx = jnp.triu_indices(binning.nb_bins, k = 1)

        #Vector of all possible separations
        sep_vec = jnp.hypot(binning.xBar_bins[idx[0]] - binning.xBar_bins[idx[1]],
                            binning.yBar_bins[idx[0]] - binning.yBar_bins[idx[1]])

        #Vector of (v_i - v_j)^2 
        v_vec = (v_bin_vec[idx[0]] - v_bin_vec[idx[1]])**2

        ### PREVIOUS VERSION
        #Now compute binned statistics
        #Average SF in each bin
        #bin_means, bin_edges, binnumber = stats.binned_statistic(sep_vec, v_vec, 'mean', bins = self.bins)
        #Average distance in each bin
        #bin_dists, bin_edges, binnumber = stats.binned_statistic(sep_vec, sep_vec, 'mean', bins = self.bins)

        ### JAX VERSION
        hist_weighted, bin_edges = jnp.histogram(sep_vec, bins = self.bins, weights = v_vec)
        hist_numbers, bin_edges = jnp.histogram(sep_vec, bins = self.bins)
        hist_dists, _ = jnp.histogram(sep_vec, bins = self.bins, weights = sep_vec)

        #Average SF in each bin
        bin_means = hist_weighted/hist_numbers

        #Average distance in each bin
        hist_dists = hist_dists/hist_numbers


        #Note : in principle, we shouldn't be taking the average distance in each bin, we should
        #take the bin center, but that's for comparison purposes with Edo's code

        return hist_dists, bin_means

__init__(bins=np.geomspace(1, 40, 15))

Initialize

Parameters:

Name Type Description Default
bins array

Bins over which the structure function is computed, in units of pixels.

geomspace(1, 40, 15)
Source code in src/xifu_cluster_sim/structure_function.py
17
18
19
20
21
22
23
24
25
26
27
def __init__(self,
            bins = np.geomspace(1,40,15)
            ):
    """
    Initialize

    Parameters:
        bins (np.array): Bins over which the structure function is computed, in units of pixels.
    """

    self.bins = bins

compute_from_map(binning, v_map)

Computes the 2nd order structure function of a binned image with arbitrary binning.

Parameters:

Name Type Description Default
binning binning

Binning instance

required
v_bin_vec array

Map of the binned values

required

Returns:

Name Type Description
bin_dists array

Separations of the SF

bin_means array

Values of the SF

Source code in src/xifu_cluster_sim/structure_function.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def compute_from_map(self, binning, v_map):
    """
    Computes the 2nd order structure function of a binned image with arbitrary binning.

    Parameters:
        binning (binning): Binning instance
        v_bin_vec (jnp.array): Map of the binned values

    Returns:
        bin_dists (jnp.array): Separations of the SF
        bin_means (jnp.array): Values of the SF
    """

    v_bin_vec = jnp.ones(binning.nb_bins)
    v_bin_vec = v_bin_vec.at[binning.bin_num_pix].set(v_map[binning.X_pixels,
                                                            binning.Y_pixels])

    #Indexes of all possible combinations
    idx = jnp.triu_indices(binning.nb_bins, k = 1)

    #Vector of all possible separations
    sep_vec = jnp.hypot(binning.xBar_bins[idx[0]] - binning.xBar_bins[idx[1]],
                        binning.yBar_bins[idx[0]] - binning.yBar_bins[idx[1]])

    #Vector of (v_i - v_j)^2 
    v_vec = (v_bin_vec[idx[0]] - v_bin_vec[idx[1]])**2

    ### PREVIOUS VERSION
    #Now compute binned statistics
    #Average SF in each bin
    #bin_means, bin_edges, binnumber = stats.binned_statistic(sep_vec, v_vec, 'mean', bins = self.bins)
    #Average distance in each bin
    #bin_dists, bin_edges, binnumber = stats.binned_statistic(sep_vec, sep_vec, 'mean', bins = self.bins)

    ### JAX VERSION
    hist_weighted, bin_edges = jnp.histogram(sep_vec, bins = self.bins, weights = v_vec)
    hist_numbers, bin_edges = jnp.histogram(sep_vec, bins = self.bins)
    hist_dists, _ = jnp.histogram(sep_vec, bins = self.bins, weights = sep_vec)

    #Average SF in each bin
    bin_means = hist_weighted/hist_numbers

    #Average distance in each bin
    hist_dists = hist_dists/hist_numbers


    #Note : in principle, we shouldn't be taking the average distance in each bin, we should
    #take the bin center, but that's for comparison purposes with Edo's code

    return hist_dists, bin_means

compute_from_vector(binning, v_bin_vec)

Computes the 2nd order structure function from a vector. This vector is taken from a binning, where the i-th value of the vector is the value in the i-th bin of the map.

Parameters:

Name Type Description Default
binning binning

Binning instance

required
v_bin_vec array

Array of the value in each bin

required

Returns:

Name Type Description
bin_dists array

Separations of the SF

bin_means array

Values of the SF

Source code in src/xifu_cluster_sim/structure_function.py
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def compute_from_vector(self,
                    binning,
                    v_bin_vec):
    """
    Computes the 2nd order structure function from a vector.
    This vector is taken from a binning, where the i-th value of the vector is the value in the i-th bin of the map.

    Parameters:
        binning (binning): Binning instance
        v_bin_vec (jnp.array): Array of the value in each bin


    Returns:
        bin_dists (jnp.array): Separations of the SF
        bin_means (jnp.array): Values of the SF
    """

    #Indexes of all possible combinations
    idx = jnp.triu_indices(len(binning.xBar_bins), k = 1)

    #Vector of all possible separations
    sep_vec = jnp.hypot(binning.xBar_bins[idx[0]] - binning.xBar_bins[idx[1]],
                        binning.yBar_bins[idx[0]] - binning.yBar_bins[idx[1]])

    #Vector of (v_i - v_j)^2 
    v_vec = (v_bin_vec[idx[0]] - v_bin_vec[idx[1]])**2

    ### PREVIOUS VERSION
    #Now compute binned statistics
    #Average SF in each bin
    #bin_means, bin_edges, binnumber = stats.binned_statistic(sep_vec, v_vec, 'mean', bins = self.bins)
    #Average distance in each bin
    #bin_dists, bin_edges, binnumber = stats.binned_statistic(sep_vec, sep_vec, 'mean', bins = self.bins)

    ### JAX VERSION
    hist_weighted, bin_edges = jnp.histogram(sep_vec, bins = self.bins, weights = v_vec)
    hist_numbers, bin_edges = jnp.histogram(sep_vec, bins = self.bins)
    hist_dists, _ = jnp.histogram(sep_vec, bins = self.bins, weights = sep_vec)

    #Average SF in each bin
    bin_means = hist_weighted/hist_numbers

    #Average distance in each bin
    hist_dists = hist_dists/hist_numbers


    #Note : in principle, we shouldn't be taking the average distance in each bin, we should
    #take the bin center, but that's for comparison purposes with Edo's code
    #For most cases, with a lot of values in each bin, the average is equivalent with the bin center.

    return hist_dists, bin_means