Numpy:np.abs在引擎盖下是如何工作的?

Numpy:np.abs在引擎盖下是如何工作的?,numpy,go,implementation,absolute,Numpy,Go,Implementation,Absolute,我试图在Go中实现我自己的gonum密集向量的绝对函数。我在想是否有比平方和平方根更好的方法来获得数组的绝对值 我的主要问题是,我必须在这些向量上实现我自己的元素牛顿平方根函数,并且在实现速度和精度之间取得平衡。如果我能避免使用这个平方根函数,我会很高兴的。NumPy源代码可能很难导航,因为它有太多用于太多数据类型的函数。您可以在文件中找到绝对值函数的C级源代码。该文件实际上是一个包含函数定义的模板,这些函数定义稍后由构建系统为几种数据类型复制。注意,每个函数都是为数组的每个元素运行的“内核”(

我试图在Go中实现我自己的gonum密集向量的绝对函数。我在想是否有比平方和平方根更好的方法来获得数组的绝对值


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

NumPy源代码可能很难导航,因为它有太多用于太多数据类型的函数。您可以在文件中找到绝对值函数的C级源代码。该文件实际上是一个包含函数定义的模板,这些函数定义稍后由构建系统为几种数据类型复制。注意,每个函数都是为数组的每个元素运行的“内核”(在数组中循环是在其他地方完成的)。这些函数始终称为
\u ctype\u absolute
,其中
是它应用的数据类型,通常是模板化的。让我们检查一下

/**开始重复
*#name=ubyte、ushort、uint、ulong、ulonglong#
*/
#定义@name@_ctype_absolute @name@_ctype_positive
/**结束重复**/
这是用于无符号类型的。在本例中,绝对值与相同,它只是复制值,而不做任何操作(如果您有一个数组
a
,并且执行
+a
,则会得到绝对值)

/**开始重复
*#name=byte,short,int,long,longlong#
*#type=npy_字节,npy_短,npy_int,npy_长,npy_长#
*/
静态空隙
@name@_ctype_absolute(@type@a,@type@*out)
{
*out=(a<0?-a:a);
}
/**结束重复**/
这个是有符号整数。很简单

/**开始重复
*#name=浮点、双精度、长双精度#
*#类型=npy_浮点、npy_双精度、npy_长双精度#
*#c=f,,l#
*/
静态空隙
@name@_ctype_absolute(@type@a,@type@*out)
{
*out=npy_fabs@c@(a) );
}
/**结束重复**/
这是针对浮点值的。这里使用了
npy_fabsf
npy_fabs
npy_fabsl
函数。它们在中声明,但通过中的模板化C代码定义,本质上调用(除非C99不可用)。您可能认为前面的代码也适用于浮点类型,但实际上它们更复杂,因为它们有NaN、无穷大或带符号的零,所以最好使用可靠地处理所有问题的标准C函数

静态无效
绝对值(npy_一半,npy_一半*输出)
{
*输出=a&0x7fffu;
}
这实际上不是模板化的,它是的绝对值函数。事实证明,您可以通过按位操作(将第一位设置为0)来更改符号,因为半精度比其他浮点类型更简单(如果有更多限制的话)(这些类型通常相同,但有特殊情况)

/**开始重复
*#name=cfloat、cdouble、clongdouble#
*#type=npy\u cfloat,npy\u cdouble,npy\u clongdouble#
*#rtype=npy_浮点、npy_双精度、npy_长双精度#
*#c=f,,l#
*/
静态空隙
@name@_ctype_absolute(@type@a,@rtype@*out)
{
*out=npy_cabs@c@(a) );
}
/**结束重复**/

最后一个用于复杂类型。它们使用
npy_cabsf
npycabs
npy_cabsl
函数,在本例中再次声明,但在使用中实现了该模板(除非该模板不可用,在这种情况下是可用的)。

谢谢!这是一个非常详细和彻底的回答。我现在知道了一些我没有意识到我需要知道的事情!因此,这确实比我想象的帮助更大。所以,如果我理解正确的话,它们的主要区别在于它们处理不同的数据类型,但本质上它们(几乎)都在数组上执行非常低的级别和快速的for循环,并将每个元素与0进行比较?@edentrain或者,是的,一般来说,你可以这么说。