2013-11-21 16 views
6

デカルト座標系とn-spherical oneを効率的に変更する方法はありますか?次のように変換は、次のとおりです。 enter image description here直交座標系へのn球座標系

以下に私のコードですが、私は、ループを取り除きたい:

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]))) 
+0

をnumpyのために高速で失います。私は最後の座標、すなわちx_nを含んでいません! – Cupitor

答えて

6

、すなわち

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 

しかし、それでもまだ、私は自分のコードが正しくない実現ベースのアプローチ

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 
+0

ありがとうございます。私のコードが正しくないことに気付きました。私は最後の座標、すなわちx_nを含んでいません! – Cupitor

+0

@ Najiそれを修正するのは難しくありません。すべての評価はすでに完了しています。私は正しい実装に私の答えを更新し、あなたにあなたを残し;) – alko

+1

はい私はすでにやりました。私はちょうどあなたに知らせていた:D – Cupitor

4

私の提案:そして、それにcumprodを使用し、1つのベクトルで洞を組み立てそのそれぞれをその余弦で多重化する。

あなたの元のコードは、中間 sin製品を暗記して高速化することができる