Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果在numpy中将float64数组压缩为float32,我应该担心什么?_Python_Numpy_Floating Point_Compression - Fatal编程技术网

Python 如果在numpy中将float64数组压缩为float32,我应该担心什么?

Python 如果在numpy中将float64数组压缩为float32,我应该担心什么?,python,numpy,floating-point,compression,Python,Numpy,Floating Point,Compression,这是一种特殊的有损压缩,很容易在numpy中实现 原则上,我可以直接比较原始的(float64)和重建的(float64(float32(original))并知道最大错误之类的事情 除了查看实际数据的最大误差外,是否有人知道这会造成何种类型的失真,例如,作为原始值大小的函数 我是否最好首先将所有值(64位)映射到[-1,1]上(作为极值的一部分,可以保留在64位),以利用接近零的更大浮点数密度 我想增加一个具体的例子,假设500k到1e6的值在-20到20之间,这是大约IID正常值(mu=0,

这是一种特殊的有损压缩,很容易在numpy中实现

原则上,我可以直接比较原始的(float64)和重建的(float64(float32(original))并知道最大错误之类的事情

除了查看实际数据的最大误差外,是否有人知道这会造成何种类型的失真,例如,作为原始值大小的函数

我是否最好首先将所有值(64位)映射到[-1,1]上(作为极值的一部分,可以保留在64位),以利用接近零的更大浮点数密度


我想增加一个具体的例子,假设500k到1e6的值在-20到20之间,这是大约IID正常值(mu=0,sigma=4),所以它们已经非常集中在零附近,并且“20”是~5-sigma罕见的。假设它们是科学测量,其真实精度比64位浮点低很多,但很难确切知道。我有大量单独的实例(可能是TB的值),因此压缩有很多实用价值,而浮点32是一种快速获得50%的方法(如果有什么区别的话,使用额外一轮无损压缩(如gzip)效果更好。)因此“-20到20”消除了很多关于真正大值的担忧。

float32的指数要小得多(负指数的情况下更大),但假设所有数字都小于该值,则只需担心精度损失。float32仅适用于约7或8位有效十进制数字。以下假设您使用的是标准IEEE-754浮点运算,这在通常的四舍五入到最近模式下很常见(有些例外)

如果双精度值在浮点值的正常范围内,则双精度值四舍五入为浮点值时发生的唯一变化是有效位(值的分数部分)从53位四舍五入为24位。这将导致最多1/2 ULP(最小精度单位)的误差。浮点数的ULP是两个最大功率的2-23倍,但不大于浮点数。例如,如果浮点数为7.25,则两个最大功率中的最大功率不大于4,则其ULP为4*2-23=2-21,约为4.77e-7。因此,在间隔中加倍时的误差[4,8)转换为浮点数的最大值为2-22,约为2.38e-7。例如,如果浮点数约为.03,则两个浮点数中的最大幂不大于2-6,因此ULP为2-29,转换为双精度时的最大误差为2-30

这些都是绝对误差。相对误差小于2-24,即1/2 ULP除以该值的最小值(特定ULP区间内的最小值,因此限制该值的2的幂)。例如,对于[4,8]中的每个数字x,我们知道数字至少是4,误差最多是2-22,所以相对误差最多是2-22/4=2-24。(误差不可能精确到2-24,因为将2的精确幂从浮点转换为双精度时没有误差,所以只有当x大于4时才有误差,所以相对误差小于,不等于,2-24。)如果您对转换的值了解得更多,例如,它比4更接近8,则可以更严格地限制错误

如果数字超出浮点的正常范围,则错误可能会更大。最大有限浮点值为2128-2104,约为3.40e38。当转换为1/2 ULP的双精度浮点时(对于浮点;双精度浮点具有更精细的ULP)大于或大于浮点值时,返回无穷大,这当然是一个无限绝对误差和一个无限相对误差。(大于最大有限浮点值但大于1/2 ULP的双精度将转换为最大有限浮点值,并具有上一段中讨论的相同误差。)

最小正正常浮动为2-126,约为1.18e-38。数字在1/2 ULP范围内(含1/2 ULP)转换为它,但小于该值的数字将转换为特殊的非规范化格式,其中ULP固定为2-149。绝对误差最大为1/2 ULP,2-150。相对误差将显著取决于转换的值

上面讨论的是正数。负数的误差是对称的

如果double的值可以精确地表示为float,则转换过程中没有错误

将输入数字映射到一个新的区间可以减少特定情况下的错误。作为一个人为的例子,假设所有数字都是区间[248,248+224]中的整数。然后将它们转换为float将丢失所有区分值的信息;它们都将被转换为248。但是将它们映射到[0224)将保留所有信息;每个不同的输入将转换为不同的结果


哪个映射最适合您的目的取决于您的具体情况。

简单的转换不太可能显著减少错误,因为您的分布以零为中心

缩放只能通过两种方式产生效果:一种,它将值从单精度值的非标准化区间移动(-2-126,2-126)。(例如,如果乘以[2-249,2-126]中的2123个值,这些值将映射到[2-126,2-3],这在非标准化区间之外。)第二种,它会改变值位于每个“二进制”中的位置(从二的一次幂到下一次幂的间隔)例如,您的最大值为20,其中相对误差可能为1/2 ULP/20,其中该二进制代码的ULP为16*2-23=2-19,因此相对误差可能为1/2*2-19/20,约为4.77e-8。假设您按32/20进行缩放,则刚好低于20的值变成刚好低于32的值。然后,当您转换为浮点时,相对误差最多为1/2*2-19/32(或略低于32),约为2.98e-8。因此您可以稍微减小误差

关于前者,如果你的价值观