array.h#

#include <sif/utils/array.h>
SIF_UTILS_ARRAY_H#

Constructors and reductions for flat sif_real arrays.

The constructors mirror the numpy functions of the same name, so a pipeline prototyped in Python translates without re-deriving the bin edges.

Warning

Every array returned here is cache-line aligned memory from sif_malloc_aligned(). Release it with sif_free_aligned(), never with free().

sif_real *sif_array_zeros(uint64_t size)#

Array of size zeros. Equivalent to np.zeros.

Returns:

Owned array, or NULL on failure or if size is 0.

sif_real *sif_array_ones(uint64_t size)#

Array of size ones. Equivalent to np.ones.

Returns:

Owned array, or NULL on failure or if size is 0.

sif_real *sif_array_full(uint64_t size, sif_real fill_value)#

Array of size copies of fill_value. Equivalent to np.full.

Returns:

Owned array, or NULL on failure or if size is 0.

sif_real *sif_array_linspace(sif_real start, sif_real stop, uint64_t num)#

num evenly spaced samples over the closed interval [start, stop]. Equivalent to np.linspace.

Both endpoints are included, so consecutive samples are separated by (stop - start) / (num - 1), and the last element is assigned stop exactly rather than accumulated, which would drift. num of 1 yields {start}.

Returns:

Owned array of num elements, or NULL on failure.

sif_real *sif_array_arange(sif_real start, sif_real stop, sif_real step, uint64_t *out_size)#

Evenly spaced values over the half-open interval [start, stop). Equivalent to np.arange.

The element count follows from the step rather than being given, so it is reported through out_size.

Parameters:
  • start – First value.

  • stop – Exclusive upper bound. May be below start if step is negative.

  • step – Spacing. Must not be zero.

  • out_size – Written with the number of elements produced, including 0 for an empty or rejected range. May not be NULL if the result is to be used.

Returns:

Owned array, or NULL for an empty range, a zero step, or on failure.

sif_real *sif_array_logspace(sif_real start, sif_real stop, uint64_t num, sif_real base)#

num values spaced evenly on a log scale, from base^start to base^stop. Equivalent to np.logspace.

Note that the exponents are evenly spaced, not the values: the endpoints are powers of base, not start and stop themselves. As with sif_array_linspace() the final element is computed directly from stop.

Returns:

Owned array of num elements, or NULL on failure.

sif_real sif_array_sum(const sif_real *arr, uint64_t size)#

Sum of every element.

Returns:

The sum; 0 for an empty or NULL array.

Note

The array is split into a fixed number of blocks, each accumulated in double and combined in index order, so the result depends on the input alone and not on how many threads happened to run. It is also markedly more accurate than a running sif_real total in a single-precision build, where a few million similar terms are enough to stall the accumulator.

sif_real sif_array_min(const sif_real *arr, uint64_t size)#

Smallest element.

Returns:

The minimum, or 0 for an empty or NULL array – which is indistinguishable from a genuine minimum of 0. Check size first if the difference matters.

Warning

The release build compiles with -ffast-math, which lets the compiler assume no NaN ever occurs, so an array containing one has no defined result. The reduction is seeded with #SIF_REAL_MAX_VAL rather than with the first element, which keeps a NaN from capturing everything behind it wherever the comparison does behave – but that is damage control, not a guarantee. Screen for NaN before reducing if the data can carry it.

sif_real sif_array_max(const sif_real *arr, uint64_t size)#

Largest element.

Returns:

The maximum, or 0 for an empty or NULL array – which is indistinguishable from a genuine maximum of 0. Check size first if the difference matters.

Warning

NaN carries the same caveat as sif_array_min().