Skip to content

Array Operations

Contains a series of functions for performing paraxial operations on arrays.

pad_to

Paraxially zero-pads the input array to the shape (npixels, npixels). Due to the paraxial requirement, the input array must be square and even arrays can only be padded to even shapes, and odd shaped arrays can only be padded to odd shapes.

Parameters:

Name Type Description Default
array Array

The input array to pad.

required
npixels int

The size to pad to the array to.

required

Returns:

Name Type Description
array Array

The padded array.

Source code in src/dLux/utils/array_ops.py
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
def pad_to(array: Array, npixels: int) -> Array:
    """
    Paraxially zero-pads the input array to the shape (npixels, npixels). Due to the
    paraxial requirement, the input array must be square and even arrays can only
    be padded to even shapes, and odd shaped arrays can only be padded to odd shapes.

    Parameters
    ----------
    array : Array
        The input array to pad.
    npixels : int
        The size to pad to the array to.

    Returns
    -------
    array : Array
        The padded array.
    """
    npixels_in = array.shape[-1]
    if npixels_in % 2 != npixels % 2:
        raise ValueError(
            "Only supports even -> even or odd -> odd padding."
            f"Input array has {npixels_in} pixels, and requested padding to "
            f"{npixels} pixels"
        )
    if npixels < npixels_in:
        raise ValueError(
            "npixels must be larger than the current array, "
            f"npixels_in = {npixels_in} < npixels = {npixels}"
        )

    return np.pad(array, (npixels - npixels_in) // 2)

crop_to

Paraxially crops the input array to the shape (npixels, npixels). Due to the paraxial requirement, the input array must be square and even arrays can only be cropped to even shapes, and odd shaped arrays can only be cropped to odd shapes.

Parameters:

Name Type Description Default
array Array

The input array to crop.

required
npixels int

The size to crop the array to.

required

Returns:

Name Type Description
array Array

The cropped array.

Source code in src/dLux/utils/array_ops.py
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
def crop_to(array: Array, npixels: int) -> Array:
    """
    Paraxially crops the input array to the shape (npixels, npixels). Due to the
    paraxial requirement, the input array must be square and even arrays can only
    be cropped to even shapes, and odd shaped arrays can only be cropped to odd shapes.

    Parameters
    ----------
    array : Array
        The input array to crop.
    npixels : int
        The size to crop the array to.

    Returns
    -------
    array : Array
        The cropped array.
    """
    npixels_in = array.shape[-1]
    if npixels_in % 2 != npixels % 2:
        raise ValueError(
            "Only supports even -> even or odd -> odd cropping."
            f"Input array has {npixels_in} pixels, and requested cropping to "
            f"{npixels} pixels"
        )
    if npixels > npixels_in:
        raise ValueError(
            "npixels must be smaller than the current array, "
            f"npixels_in = {npixels_in} > npixels = {npixels}"
        )

    start, stop = (npixels_in - npixels) // 2, (npixels_in + npixels) // 2
    return array[start:stop, start:stop]

resize

Resizes the input array to the shape (npixels, npixels), using either a pad or crop depending on the input array size. Due to the paraxial requirement, the input array must be square and even arrays can only be resized to even shapes, and odd shaped arrays can only be resized to odd shapes.

Parameters:

Name Type Description Default
array Array

The input array to resize.

required
npixels int

The size to output the array.

required

Returns:

Name Type Description
array Array

The resized array.

Source code in src/dLux/utils/array_ops.py
 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
def resize(array: Array, npixels: int) -> Array:
    """
    Resizes the input array to the shape (npixels, npixels), using either a pad or crop
    depending on the input array size. Due to the paraxial requirement, the input array
    must be square and even arrays can only be resized to even shapes, and odd shaped
    arrays can only be resized to odd shapes.

    Parameters
    ----------
    array : Array
        The input array to resize.
    npixels : int
        The size to output the array.

    Returns
    -------
    array : Array
        The resized array.
    """
    npixels_in = array.shape[-1]

    if npixels == npixels_in:
        return array
    elif npixels < npixels_in:
        return crop_to(array, npixels)
    else:
        return pad_to(array, npixels)

downsample

Downsamples the input array by a factor of n, either by taking the mean or sum of the array.

Parameters:

Name Type Description Default
array Array

The input array to downsample.

required
n int

The factor by which to downsample the array.

required
mean bool = True

Whether to downsample by taking the mean or sum of the array.

True

Returns:

Name Type Description
array Array

The downsampled array.

Source code in src/dLux/utils/array_ops.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
def downsample(array: Array, n: int, mean: bool = True) -> Array:
    """
    Downsamples the input array by a factor of n, either by taking the mean or sum
    of the array.

    Parameters
    ----------
    array : Array
        The input array to downsample.
    n : int
        The factor by which to downsample the array.
    mean : bool = True
        Whether to downsample by taking the mean or sum of the array.

    Returns
    -------
    array : Array
        The downsampled array.
    """
    if array.shape[0] != array.shape[1]:
        raise ValueError(
            f"Input array has shape {array.shape}, which is not square"
        )
    if array.shape[0] % n != 0:
        raise ValueError(
            f"Input array has {array.shape[0]} pixels, which is not divisible "
            f"by {n}"
        )

    method = np.mean if mean else np.sum
    size_in = array.shape[0]
    size_out = size_in // n

    # Downsample first dimension
    array = method(array.reshape((size_in * size_out, n)), 1)
    array = array.reshape(size_in, size_out).T

    # Downsample second dimension
    array = method(array.reshape((size_out * size_out, n)), 1)
    array = array.reshape(size_out, size_out).T
    return array