interprets_fractional_indexing

PlasmaCalcs.tools.arrays.interprets_fractional_indexing(indexer, L=None, *, rounding=UNSET)

interprets any fractional values, i.e. non-integers between -1 and 1.

returns indexer in “canonical” form, no longer containing any fractional values.
If indexer contains no fractional values, return indexer unchanged.
indexer: None, int, slice, iterable, or non-integer between -1 and 1.
indexer to interpret; might contain fractional value(s), i.e. non-integers between -1 and 1.
any fractional values will be converted to value*(L+1), then rounded to an integer.
rounding method is determined by rounding, unless indexer is a slice,
in which case rounding for start & stop is handled differently.
fractional values might appear in any of the following ways:
- as an individual float, e.g. 0.3
- as a float inside an iterable, e.g. [0, 0.25, 0.5, 0.75, 1]
- as a float inside a slice, e.g. slice(0, -0.1, 0.02)
“fractional” is tested via (-1 < value < 1) and (value != 0).
L: None or int
length of the object being indexed. Required if any fractional values provided.
None –> if any fractional values provided, raise InputMissingError.
L must be >= 2. [TODO] handle L=1 case (have all fractional values imply 0).
rounding: UNSET, ‘round’, ‘floor’, ‘ceil’ or ‘int’
method to use for rounding fractional values to integers, except for slice.start or slice.stop.
UNSET –> use DEFAULTS.FRACTIONAL_INDEX_ROUNDING (default: floor)
‘round’ –> as per builtins.round(). round to nearest integer, ties toward even integers.
‘int’ –> as per builtins.int(). round towards 0.
‘floor’ –> as per math.floor(). round towards negative infinity.
‘ceil’ –> as per math.ceil(). round towards positive infinity.
Rounding for slice.start and start.stop will ALWAYS include all indices between start*(L-1) and stop*(L-1)
For positive (or None) step, this means: round all numbers toward +infinity.
Examples (floats here are after multiplying input by L-1, e.g. 0.1 * 153 –> 15.3):
slice(15.3, 29.2, 1) –> slice(16, 30, 1) # 15.3, [16, 17, …, 29], 29.2
slice(-29.2, -15.3, 1) –> slice(-29, -15, 1) # -29.2, [-29, -28, …, -16], -15.3
slice(15.3, -15.3, 1) –> slice(16, -15, 1) # 15.3, [16, 18, …, -17, -16], -15.3
slice(-29.2, 100.1, 1) –> slice(-29, 101, 1) # -29.2, [-29, -28, …, 99, 100], 100.1
For negative step, this means: round all numbers toward -infinity.
Examples (floats here are after multiplying input by L-1, e.g. 0.1 * 153 –> 15.3):
slice(29.2, 15.3, -1) –> slice(29, 15, -1) # 29.2, [29, 28, …, 17, 16], 15.3
slice(-15.3, -29.2, -1) –> slice(-16, -30, -1) # -15.3, [-16, -17, …, -28, -29], -29.2
slice(-15.3, 15.3, -1) –> slice(-16, 15, -1) # -15.3, [-16, -17, …, 16, 15], 15.3
slice(100.1, -29.2, -1) –> slice(100, -30, -1) # 100.1, [100, 99, …, -28, -29], -29.2
Rounding mode for slice.step is determined by rounding, applying to step*L (not L-1).
however if this causes step=0, instead use step=1 or step=-1, based on sign of original step.
— Examples —
# [TODO] update these when considering N = L-1 is what is actually being multiplied.
interprets_fractional_indexing(0.5, L=10) –> 5
interprets_fractional_indexing(slice(0.2, 0.9, 0.1), L=10) –> slice(2, 9, 1)
interprets_fractional_indexing([0.2, 0.5, -3, 8, 7, 0.9], L=10) –> [2, 5, -3, 8, 7, 9]
interprets_fractional_indexing(0.23, L=10, rounding=’int’) –> 2
interprets_fractional_indexing(0.23, L=10, rounding=’ceil’) –> 3