Numpy:np.abs 实际上是如何工作的?

我正在尝试在 Go 中为 gonum 密集向量实现我自己的绝对函数。我在想是否有比先平方再平方根更好的方法来获取数组的绝对值?

我的主要问题是我必须在这些向量上实现我自己的元素明智的牛顿平方根函数,并且在实现速度和准确性之间存在平衡。如果我能避免使用这个平方根函数,我会很高兴。


江户川乱折腾
浏览 64回答 1
1回答

温温酱

NumPy 源代码可能很难浏览,因为它具有适用于多种数据类型的多种功能。您可以在文件中找到绝对值函数的 C 级源代码scalarmath.c.src。该文件实际上是一个带有函数定义的模板,构建系统稍后会为多种数据类型复制这些函数定义。请注意,每个函数都是为数组的每个元素运行的“内核”(循环遍历数组是在其他地方完成的)。这些函数总是被称为<name of the type>_ctype_absolute,其中<name of the type>是它适用的数据类型并且通常是模板化的。让我们通过它们。/**begin repeat * #name = ubyte, ushort, uint, ulong, ulonglong# */#define @name@_ctype_absolute @name@_ctype_positive/**end repeat**/这个是针对无符号类型的。在这种情况下,绝对值与 相同np.positive,它只是复制值而不做任何事情(如果你有一个数组a并且你这样做,它就是你得到的+a)。/**begin repeat * #name = byte, short, int, long, longlong# * #type = npy_byte, npy_short, npy_int, npy_long, npy_longlong# */static void@name@_ctype_absolute(@type@ a, @type@ *out){    *out = (a < 0 ? -a : a);}/**end repeat**/这个用于有符号整数。非常简单。/**begin repeat * #name = float, double, longdouble# * #type = npy_float, npy_double, npy_longdouble# * #c = f,,l# */static void@name@_ctype_absolute(@type@ a, @type@ *out){    *out = npy_fabs@c@(a);}/**end repeat**/这适用于浮点值。这里npy_fabsf,npy_fabs和npy_fabsl函数被使用。这些在 中声明npy_math.h,但通过模板化的 C 代码在 中定义npy_math_internal.h.src,本质上调用C/C99 对应项(除非 C99 不可用,在这种情况下fabsf并fabsl用 模拟fabs)。您可能认为前面的代码应该也适用于浮点类型,但实际上这些更复杂,因为它们有 NaN、无穷大或带符号的零之类的东西,所以最好使用处理所有问题的标准 C 函数可靠地。static voidhalf_ctype_absolute(npy_half a, npy_half *out){    *out = a&0x7fffu;}这实际上不是模板化的,它是半精度浮点值的绝对值函数。原来你可以通过按位运算(将第一位设置为 0)来更改符号,因为半精度比其他浮点类型更简单(如果更有限)(对于那些通常是相同的,但有特殊情况)./**begin repeat * #name = cfloat, cdouble, clongdouble# * #type = npy_cfloat, npy_cdouble, npy_clongdouble# * #rtype = npy_float, npy_double, npy_longdouble# * #c = f,,l# */static void@name@_ctype_absolute(@type@ a, @rtype@ *out){    *out = npy_cabs@c@(a);}/**end repeat**/最后一个用于复杂类型。这些使用npy_cabsf和npycabs函数npy_cabsl,再次在中声明,但在本例中使用C99 函数npy_math.h进行模板实现(除非该函数不可用,在这种情况下,它是用模拟的)。npy_math_complex.c.srcnp.hypot
打开App,查看更多内容
随时随地看视频慕课网APP