n-球坐标系转换为笛卡尔坐标系

8
有没有一种有效的方法可以在直角坐标系和n-spherical one之间进行转换?转换如下: enter image description here 以下是我的代码,但我想摆脱循环:
import numpy as np
import scipy.sparse

    def coord_transform_n(r,alpha):
        """alpha: the n-2 values between [0,\pi) and last one between [0,2\pi)
        """
        x=[]
        for i in range(alpha.shape[0]):
            x.append(r*np.prod(np.sin(alpha[0:i]))*np.cos(alpha[i]))
        return np.asarray(x)
    print coord_transform_n(1,np.asarray(np.asarray([1,2])))

我意识到我的代码不正确。我没有包括最后一个坐标,即x_n! - Cupitor
2个回答

7
您的原始代码可以通过记忆中间的 sin 乘积来加速,即:
def ct_dynamic(r, alpha):
    """alpha: the n-2 values between [0,\pi) and last one between [0,2\pi)
    """
    x = np.zeros(len(alpha) + 1)
    s = 1
    for e, a in enumerate(alpha):
        x[e] = s*np.cos(a)
        s *= np.sin(a)
    x[len(alpha)] = s
    return x*r

但仍然比基于numpy的方法慢。

def ct(r, arr):
    a = np.concatenate((np.array([2*np.pi]), arr))
    si = np.sin(a)
    si[0] = 1
    si = np.cumprod(si)
    co = np.cos(a)
    co = np.roll(co, -1)
    return si*co*r

>>> n = 10
>>> c = np.random.random_sample(n)*np.pi
>>> all(ct(1,c) == ct_dynamic(1,c))
True

>>> timeit.timeit('from __main__ import coord_transform_n as f, c; f(2.4,c)', number=10000)
2.213547945022583

>>> timeit.timeit('from __main__ import ct_dynamic as f, c; f(2.4,c)', number=10000)
0.9227950572967529

>>> timeit.timeit('from __main__ import ct as f, c; f(2.4,c)', number=10000)
0.5197498798370361

非常感谢。我意识到我的代码不正确。我没有包括最后一个坐标,即x_n! - Cupitor
@Naji,修复它并不难,所有的评估都已经完成了。我更新了我的答案来纠正实现,你可以留下你的答案;) - alko

3
我的建议是将正弦组装到一个向量中,然后在该向量上使用cumprod函数,接着将每个元素乘以余弦(在另一个向量中预先组装)。请保留html标记。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接