rig.type_casts: numerical type conversions for SpiNNaker

Fixed point conversion utilities.

rig.type_casts.float_to_fp(signed, n_bits, n_frac)[source]

Return a function to convert a floating point value to a fixed point value.

For example, a function to convert a float to a signed fractional representation with 8 bits overall and 4 fractional bits (S3.4) can be constructed and used with:

>>> s34 = float_to_fp(signed=True, n_bits=8, n_frac=4)
>>> hex(int(s34(0.5)))
'0x8'

The fixed point conversion is saturating:

>>> q34 = float_to_fp(False, 8, 4)  # Unsigned 4.4
>>> hex(int(q34(-0.5)))
'0x0'

>>> hex(int(q34(15.0)))
'0xf0'

>>> hex(int(q34(16.0)))
'0xff'
Parameters:
signed : bool

Whether the values that are to be converted should be signed, or clipped at zero.

>>> hex(int(float_to_fp(True, 8, 4)(-0.5)))  # Signed
'-0x8'
>>> hex(int(float_to_fp(False, 8, 4)(-0.5)))  # Unsigned
'0x0'
n_bits : int

Total number of bits in the fixed-point representation (including sign bit and fractional bits).

n_frac : int

Number of fractional bits in the fixed-point representation.

rig.type_casts.fp_to_float(n_frac)[source]

Return a function to convert a fixed point value to a floating point value.

For example, a function to convert from signed fractional representations with 4 fractional bits constructed and used with:

>>> f = fp_to_float(4)
>>> f(0x08)
0.5

>>> f(-0x8)
-0.5

>>> f(-0x78)
-7.5
Parameters:
n_frac : int

Number of fractional bits in the fixed-point representation.

rig.type_casts.float_to_fix(signed, n_bits, n_frac)[source]

DEPRECATED Return a function to convert a floating point value to a fixed point value.

Warning

This function is deprecated in favour of float_to_fp().

For example, a function to convert a float to a signed fractional representation with 8 bits overall and 4 fractional bits (S3.4) can be constructed and used with:

>>> s34 = float_to_fix(signed=True, n_bits=8, n_frac=4)
>>> hex(s34(0.5))
'0x8'

The fixed point conversion is saturating:

>>> q34 = float_to_fix(False, 8, 4)  # Unsigned 4.4
>>> hex(q34(-0.5))
'0x0'

>>> hex(q34(15.0))
'0xf0'

>>> hex(q34(16.0))
'0xff'
Parameters:
signed : bool

Whether the values that are to be converted should be signed, or clipped at zero.

>>> hex(float_to_fix(True, 8, 4)(-0.5))  # Signed
'0xf8'
>>> hex(float_to_fix(False, 8, 4)(-0.5))  # Unsigned
'0x0'

Note

Regardless of the value of the signed parameter the returned value is always an unsigned integer suitable for packing with the struct packing chars B, H, I etc.

n_bits : int

Total number of bits in the fixed-point representation (including sign bit and fractional bits).

n_frac : int

Number of fractional bits in the fixed-point representation.

Raises:
ValueError

If the number of bits specified is not possible. For example, requiring more fractional bits than there are bits overall will result in a ValueError:

>>> fix_to_float(False, 8, 9)
Traceback (most recent call last):
ValueError: n_frac: 9: Must be less than 8 (and positive).
rig.type_casts.fix_to_float(signed, n_bits, n_frac)[source]

DEPRECATED Return a function to convert a fixed point value to a floating point value.

Warning

This function is deprecated in favour of fp_to_float().

For example, a function to convert from signed fractional representations with 8 bits overall and 4 fractional representations (S3.4) can be constructed and used with:

>>> f = fix_to_float(True, 8, 4)
>>> f(0x08)
0.5

>>> f(0xf8)
-0.5

>>> f(0x88)
-7.5
Parameters:
signed : bool

Determines whether input values should be treated as signed or otherwise, e.g.:

>>> fix_to_float(True, 8, 4)(0xfc)
-0.25

>>> fix_to_float(False, 8, 4)(0xf8)
15.5

The value accepted by the returned function should always be an unsigned integer.

n_bits : int

Total number of bits in the fixed-point representation (including sign bit and fractional bits).

n_frac : int

Number of fractional bits in the fixed-point representation.

Raises:
ValueError

If the number of bits specified is not possible. For example, requiring more fractional bits than there are bits overall will result in a ValueError:

>>> fix_to_float(False, 8, 9)
Traceback (most recent call last):
ValueError: n_frac: 9: Must be less than 8 (and positive).
class rig.type_casts.NumpyFloatToFixConverter(signed, n_bits, n_frac)[source]

A callable which converts Numpy arrays of floats to fixed point arrays.

General usage is to create a new converter and then call this on arrays of values. The dtype of the returned array is determined from the parameters passed. For example:

>>> f = NumpyFloatToFixConverter(signed=True, n_bits=8, n_frac=4)

Will convert floating point values to 8-bit signed representations with 4 fractional bits. Consequently the returned dtype will be int8:

>>> import numpy as np
>>> vals = np.array([0.0, 0.25, 0.5, -0.5, -0.25])
>>> f(vals)
array([ 0,  4,  8, -8, -4], dtype=int8)

The conversion is saturating:

>>> f(np.array([15.0, 16.0, -16.0, -17.0]))
array([ 127,  127, -128, -128], dtype=int8)

The byte representation can be expected to match that for using float_to_fix:

>>> d = f(np.array([-16.0]))

>>> import struct
>>> g = float_to_fix(True, 8, 4)
>>> val = g(-16.0)
>>> struct.pack('B', val) == bytes(d.data)
True

An exception is raised if the number of bits specified cannot be represented using a whole dtype:

>>> NumpyFloatToFixConverter(True, 12, 0)
Traceback (most recent call last):
ValueError: n_bits: 12: Must be 8, 16, 32 or 64.
class rig.type_casts.NumpyFixToFloatConverter(n_frac)[source]

A callable which converts Numpy arrays of fixed point values to floating point.

General usage is to create a new converter and then call this on arrays of values. The dtype of the input array is used to determine whether the values are signed or otherwise. For example, the following creates a callable which will convert from any format which has 4 fractional bits:

>>> kbits = NumpyFixToFloatConverter(4)

This will produced signed and unsigned values depending on the dtype of the original array.

>>> signed = np.array([0xf0], dtype=np.int8)
>>> kbits(signed)
array([-1.])
>>> unsigned = np.array([0xf0], dtype=np.uint8)
>>> kbits(unsigned)[0]
15.0