New feature: binary (arbitrary base) rounding

Hi all, I hope this is the correct way to propose a new feature. https://github.com/numpy/numpy/issues/22522 Currently, the around-function supports rounding to a given number of decimal digits. It is often quite convenient to be able to round to a given number of binary digits to mimic fixed-point representations. Currently this can be readily achieved using e.g. fractional_bits = 5 scale = 2**fractional_bits x_round = np.around(x*scale)/scale However, it would be more convenient (and probably faster) to provide dedicated support for it. I see a few different ways to obtain this: 1. Provide a separate function (binaryround?) 2. Provide a base argument to around which defaults to 10. 3. Provide a quant(ization) function where the argument is the step-size. (For completeness, one may think of having multiple quantization modes, not just rounding) Any opinions? BR Oscar Gustafsson

On Thu, 2022-11-03 at 11:37 +0100, Oscar Gustafsson wrote:
Thanks for the proposal. I don't have much of an opinion on this and right now I am mainly wondering whether there is prior art which can inform us that this is relatively widely useful?
This seems more like a a place for some bit-fiddling, but I am not sure. Also a question is whether rounding modes make sense and what you want (truncate, round to even?). I suspect that this would be more something for a project similar to Warrens ufunclab: https://github.com/WarrenWeckesser/ufunclab I.e. written as a NumPy ufunc, but not in NumPy iself. - Sebastian

Den tis 8 nov. 2022 kl 11:44 skrev Sebastian Berg < sebastian@sipsolutions.net>:
Well, if designing hardware it is typically more useful than decimal rounding. Not sure what to bring up as prior art, but the whole idea is to use it to emulate fixed-point behavior. So quantizing/rounding a floating-point value to the nearest fixed-point value with a given number of fractional bits. bround(0.37, 3) = 0.011 = 0.375. Also, see ac_fixed below which is part of Algorithmic C types, ac_types, https://hlslibs.org/ supported in most high-level synthesis tools, see e.g. https://www.intel.com/content/www/us/en/develop/documentation/oneapi-fpga-op...
The "correct" way would of course be to do this using integers or ac_fixed https://github.com/hlslibs/ac_types/blob/master/include/ac_fixed.h You are correct that one would like to support different rounding modes (although for fixed-point one usually do not care as much about that as for floating-point, standard "add half LSB" rounding and truncation are typically enough). I didn't want to bring that up at this early stage.
Not sure how straightforward it is, but if one could supply the different ac_*-types as custom data types to NumPy that would be a great way of doing it. However, from a quick check it seems like it is only possible to add custom types which are "structs" of existing types. ac_typed are that in some sense (everything is internally represented as integer-types), but probably not close enough for a simple implementation. BR Oscar Gustafsson

On Thu, 2022-11-03 at 11:37 +0100, Oscar Gustafsson wrote:
Thanks for the proposal. I don't have much of an opinion on this and right now I am mainly wondering whether there is prior art which can inform us that this is relatively widely useful?
This seems more like a a place for some bit-fiddling, but I am not sure. Also a question is whether rounding modes make sense and what you want (truncate, round to even?). I suspect that this would be more something for a project similar to Warrens ufunclab: https://github.com/WarrenWeckesser/ufunclab I.e. written as a NumPy ufunc, but not in NumPy iself. - Sebastian

Den tis 8 nov. 2022 kl 11:44 skrev Sebastian Berg < sebastian@sipsolutions.net>:
Well, if designing hardware it is typically more useful than decimal rounding. Not sure what to bring up as prior art, but the whole idea is to use it to emulate fixed-point behavior. So quantizing/rounding a floating-point value to the nearest fixed-point value with a given number of fractional bits. bround(0.37, 3) = 0.011 = 0.375. Also, see ac_fixed below which is part of Algorithmic C types, ac_types, https://hlslibs.org/ supported in most high-level synthesis tools, see e.g. https://www.intel.com/content/www/us/en/develop/documentation/oneapi-fpga-op...
The "correct" way would of course be to do this using integers or ac_fixed https://github.com/hlslibs/ac_types/blob/master/include/ac_fixed.h You are correct that one would like to support different rounding modes (although for fixed-point one usually do not care as much about that as for floating-point, standard "add half LSB" rounding and truncation are typically enough). I didn't want to bring that up at this early stage.
Not sure how straightforward it is, but if one could supply the different ac_*-types as custom data types to NumPy that would be a great way of doing it. However, from a quick check it seems like it is only possible to add custom types which are "structs" of existing types. ac_typed are that in some sense (everything is internally represented as integer-types), but probably not close enough for a simple implementation. BR Oscar Gustafsson
participants (3)
-
Francesc Alted
-
Oscar Gustafsson
-
Sebastian Berg