2025-07-13 08:55:18 +08:00

53 lines
2.0 KiB
Python

from typing import Optional
import numpy as np
def get_timeline(range_max: int, dtype: Optional[np.dtype] = None) -> np.ndarray:
"""Returns timeline array for requirements.
Parameters
----------
range_max : int
Largest value in range. Assume `range(range_max)`. Commonly that's length of the signal.
dtype : np.dtype
Minimal definition type. Returned timeline will have dtype that's the same or with higher byte size.
"""
timeline = np.arange(0, range_max, dtype=dtype)
if timeline[-1] != range_max - 1:
inclusive_dtype = smallest_inclusive_dtype(timeline.dtype, range_max)
timeline = np.arange(0, range_max, dtype=inclusive_dtype)
return timeline
def smallest_inclusive_dtype(ref_dtype: np.dtype, ref_value) -> np.dtype:
"""Returns a numpy dtype with the same base as reference dtype (ref_dtype)
but with the range that includes reference value (ref_value).
Parameters
----------
ref_dtype : dtype
Reference dtype. Used to select the base, i.e. int or float, for returned type.
ref_value : value
A value which needs to be included in returned dtype. Value will be typically int or float.
"""
# Integer path
if np.issubdtype(ref_dtype, np.integer):
for dtype in [np.uint16, np.uint32, np.uint64]:
if ref_value < np.iinfo(dtype).max:
return dtype
max_val = np.iinfo(np.uint32).max
raise ValueError("Requested too large integer range. Exceeds max( uint64 ) == '{}.".format(max_val))
# Integer path
if np.issubdtype(ref_dtype, np.floating):
for dtype in [np.float16, np.float32, np.float64]:
if ref_value < np.finfo(dtype).max:
return dtype
max_val = np.finfo(np.float64).max
raise ValueError("Requested too large integer range. Exceeds max( float64 ) == '{}.".format(max_val))
raise ValueError("Unsupported dtype '{}'. Only intX and floatX are supported.".format(ref_dtype))