Python 余弦的真反函数,单位为numpy?(非阿科斯)

Python 余弦的真反函数,单位为numpy?(非阿科斯),python,numpy,trigonometry,Python,Numpy,Trigonometry,这是一个奇怪的例子: 我发现自己需要一个numpy函数,我称之为np.cos的真正逆函数(或者另一个三角函数,这里用余弦来定义)。我所说的“真逆”是指一个函数invcos,这样 np.cos(invcos(x)) = x 对于任何真正的浮点x。两个观察结果:invcos(x)存在(它是一个复杂的浮点)和np。arccos(x)不做这项工作,因为它只对-1

这是一个奇怪的例子:

我发现自己需要一个numpy函数,我称之为np.cos的真正逆函数(或者另一个三角函数,这里用余弦来定义)。我所说的“真逆”是指一个函数
invcos
,这样

np.cos(invcos(x)) = x
对于任何真正的浮点x。两个观察结果:
invcos(x)
存在(它是一个复杂的浮点)和
np。arccos(x)
做这项工作,因为它只对
-1
有效

我的问题是,是否有一个有效的numpy函数用于此操作,或者它是否可以轻松地从现有函数构建?

我的尝试是结合使用
np.arccos
np.arccosh
手工构建函数。这是基于这样一种观察,即
np.arccos
可以处理[-1,1]内的x,而
np.arccosh
可以处理[-1,1]外的x,如果乘以复数单位。要确保这一点有效,请执行以下操作:

cos_x = np.array([0.5, 1., 1.5])

x = np.arccos(cos_x)
cos_x_reconstucted = np.cos(x)
# [0.5 1.  nan]

x2 = 1j*np.arccosh(cos_x)
cos_x_reconstructed2 = np.cos(x2)
# [nan+nanj 1.-0.j 1.5-0.j]
所以我们可以把它和

def invcos(array):
    x1 = np.arccos(array)
    x2 = 1j*np.arccosh(array)
    print(x1)
    print(x2)
    x = np.empty_like(x1, dtype=np.complex128)
    x[~np.isnan(x1)] = x1[~np.isnan(x1)]
    x[~np.isnan(x2)] = x2[~np.isnan(x2)]
    return x

cos_x = np.array([0.5, 1., 1.5])
x = invcos(cos_x)
cos_x_reconstructed = np.cos(x)
# [0.5-0.j 1.-0.j 1.5-0.j]
这会给出正确的结果,但自然会引发运行时警告:

RuntimeWarning: invalid value encountered in arccos.
我想,既然numpy甚至告诉我我的算法效率不高,它可能就没有效率了。有更好的方法吗


对于那些对为什么这个奇怪的函数可能有用感兴趣的读者来说:动机来自物理背景。在某些理论中,可以有“脱壳”的向量分量,这意味着这些分量甚至可能比向量长。尽管如此,上面的函数仍然可以用于根据角度对事物进行参数化

我的问题是,是否有一个有效的numpy函数用于此操作,或者它是否可以轻松地从现有函数构建

对,;它是<代码>np.arccos

从文件中:

对于实值输入数据类型,arccos始终返回实际输出。对于不能表示为实数或无穷大的每个值,它将生成nan并设置无效浮点错误标志

对于复数输入,arccos是一个复杂的分析函数,它具有分支切割[-inf,-1]和[1,inf],并且从上到下在前者上是连续的

所以我们需要做的就是确保输入是一个复数(即使它的虚部为零):

对于数组,我们需要适当的
dtype

>>> np.arccos(np.ones((3,3)) * 2)
array([[nan, nan, nan],
       [nan, nan, nan],
       [nan, nan, nan]])
>>> np.arccos(np.ones((3,3), dtype=np.complex) * 2)
array([[0.-1.3169579j, 0.-1.3169579j, 0.-1.3169579j],
       [0.-1.3169579j, 0.-1.3169579j, 0.-1.3169579j],
       [0.-1.3169579j, 0.-1.3169579j, 0.-1.3169579j]])

嗯,我完全错过了那个。。。谢谢你的回答,这当然解决了问题。因为这几乎是一个原子的解决方案,我想没有比这更好的了,它会马上给你绿色的记号。谢谢和+1!
>>> np.arccos(np.ones((3,3)) * 2)
array([[nan, nan, nan],
       [nan, nan, nan],
       [nan, nan, nan]])
>>> np.arccos(np.ones((3,3), dtype=np.complex) * 2)
array([[0.-1.3169579j, 0.-1.3169579j, 0.-1.3169579j],
       [0.-1.3169579j, 0.-1.3169579j, 0.-1.3169579j],
       [0.-1.3169579j, 0.-1.3169579j, 0.-1.3169579j]])