numpy 中余弦的真反函数? (不是 arccos)
True inverse function for cosine in numpy? (NOT arccos)
这是一个奇怪的:
我发现自己需要一个 numpy 函数,我称之为 np.cos
的真反函数(或另一个三角函数,这里使用余弦来确定)。我所说的“'true inverse'”是一个函数invcos
,这样
np.cos(invcos(x)) = x
对于任何实数浮点数 x。两个观察结果:invcos(x)
存在(它是一个复杂的浮点数)并且 np.arccos(x)
确实 而不是 完成这项工作,因为它只适用于 -1 < 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]
这给出了正确的结果,但自然会引发 RuntimeWarnings:
RuntimeWarning: invalid value encountered in arccos.
我想既然 numpy 甚至告诉我我的算法效率不高,那么它可能效率不高。有更好的方法吗?
对于对为什么这个奇怪的功能可能有用感兴趣的读者:动机来自物理学背景。在某些理论中,向量分量可以是 'off-shell',这意味着分量甚至可能比向量更长。上面的函数对于根据角度对事物进行参数化仍然很有用。
My question is if there is an efficient numpy function for this operation or if it can built from existing ones easily?
是;它是... np.arccos
.
来自文档:
For real-valued input data types, arccos always returns real output. For each value that cannot be expressed as a real number or infinity, it yields nan and sets the invalid floating point error flag.
For complex-valued input, arccos is a complex analytic function that has branch cuts [-inf, -1] and [1, inf] and is continuous from above on the former and from below on the latter.
所以我们需要做的就是确保输入是一个复数(即使它的虚部为零):
>>> import numpy as np
>>> np.arccos(2.0)
__main__:1: RuntimeWarning: invalid value encountered in arccos
nan
>>> np.arccos(2 + 0j)
-1.3169578969248166j
对于数组,我们需要合适的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]])
这是一个奇怪的:
我发现自己需要一个 numpy 函数,我称之为 np.cos
的真反函数(或另一个三角函数,这里使用余弦来确定)。我所说的“'true inverse'”是一个函数invcos
,这样
np.cos(invcos(x)) = x
对于任何实数浮点数 x。两个观察结果:invcos(x)
存在(它是一个复杂的浮点数)并且 np.arccos(x)
确实 而不是 完成这项工作,因为它只适用于 -1 < 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]
这给出了正确的结果,但自然会引发 RuntimeWarnings:
RuntimeWarning: invalid value encountered in arccos.
我想既然 numpy 甚至告诉我我的算法效率不高,那么它可能效率不高。有更好的方法吗?
对于对为什么这个奇怪的功能可能有用感兴趣的读者:动机来自物理学背景。在某些理论中,向量分量可以是 'off-shell',这意味着分量甚至可能比向量更长。上面的函数对于根据角度对事物进行参数化仍然很有用。
My question is if there is an efficient numpy function for this operation or if it can built from existing ones easily?
是;它是... np.arccos
.
来自文档:
For real-valued input data types, arccos always returns real output. For each value that cannot be expressed as a real number or infinity, it yields nan and sets the invalid floating point error flag.
For complex-valued input, arccos is a complex analytic function that has branch cuts [-inf, -1] and [1, inf] and is continuous from above on the former and from below on the latter.
所以我们需要做的就是确保输入是一个复数(即使它的虚部为零):
>>> import numpy as np
>>> np.arccos(2.0)
__main__:1: RuntimeWarning: invalid value encountered in arccos
nan
>>> np.arccos(2 + 0j)
-1.3169578969248166j
对于数组,我们需要合适的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]])