Skip to content

Commit

Permalink
Optimized fast_array_util.py through vectorization
Browse files Browse the repository at this point in the history
The optimized version vectorizes the cumulative trapezoidal integration over blocks, reducing nested loops and handling size normalization for each block efficiently, ensuring the output matches the expected shape.
  • Loading branch information
DarkMatterCompiler authored Dec 22, 2024
1 parent 87e4ae1 commit 7257df4
Showing 1 changed file with 21 additions and 22 deletions.
43 changes: 21 additions & 22 deletions tardis/plasma/properties/continuum_processes/fast_array_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,44 @@ def numba_cumulative_trapezoid(f, x):
Returns
-------
numpy.ndarray, dtype float
The result of cumulative integration of f along x
The result of cumulative integration of f along x.
"""
integ = (np.diff(x) * (f[1:] + f[:-1]) / 2.0).cumsum()
return integ / integ[-1]
result = np.zeros_like(f) # Ensure the same size as `f`
result[1:] = integ / integ[-1] # Normalize and assign
return result


@njit(**njit_dict)
def cumulative_integrate_array_by_blocks(f, x, block_references):
"""
Cumulatively integrate a function over blocks.
This function cumulatively integrates a function `f` defined at
locations `x` over blocks given in `block_references`.
Perform cumulative integration over blocks using the trapezoidal rule, optimized.
Parameters
----------
f : numpy.ndarray, dtype float
Input array to integrate. Shape is (N_freq, N_shells), where
N_freq is the number of frequency values and N_shells is the number
of computational shells.
Input array to integrate (N_freq, N_shells).
x : numpy.ndarray, dtype float
The sample points corresponding to the `f` values. Shape is (N_freq,).
Sample points corresponding to `f` (1D array, shared across blocks).
block_references : numpy.ndarray, dtype int
The start indices of the blocks to be integrated. Shape is (N_blocks,).
Start indices for each block (1D array, length N_blocks).
Returns
-------
numpy.ndarray, dtype float
Array with cumulatively integrated values. Shape is (N_freq, N_shells)
same as f.
Cumulatively integrated array (N_freq, N_shells).
"""
n_rows = len(block_references) - 1
integrated = np.zeros_like(f)
for i in prange(f.shape[1]): # columns
# TODO: Avoid this loop through vectorization of cumulative_trapezoid
for j in prange(n_rows): # rows
start = block_references[j]
stop = block_references[j + 1]
integrated[start + 1 : stop, i] = numba_cumulative_trapezoid(
f[start:stop, i], x[start:stop]
)
n_blocks = len(block_references) - 1

for block_idx in range(n_blocks):
start = block_references[block_idx]
stop = block_references[block_idx + 1]

if stop - start > 1: # Ensure the block has at least two points
for col in range(f.shape[1]): # Process each column (shell)
integrated[start:stop, col] = numba_cumulative_trapezoid(
f[start:stop, col], x[start:stop]
)

return integrated

0 comments on commit 7257df4

Please sign in to comment.