2015-09-04 13 views
12

Muszę zwrócić wartość sin i cos każdego elementu w dużej tablicy. W tej chwili robię:Czy istnieje szybka metoda zwracania wartości Sin i Cos tej samej wartości w języku Python?

a,b=np.sin(x),np.cos(x) 

gdzie x jest dużą tablicą. Potrzebuję zachować informacje o znaku dla każdego wyniku, więc:

a=np.sin(x) 
b=(1-a**2)**0.5 

nie jest opcją. Czy istnieje najszybszy sposób na natychmiastowe przywrócenie zarówno grzechu, jak i cos?

+1

* sin * 90- * x * = * cos x * – tripleee

+0

Czy ja rozumiem pytanie poprawnie? Zasadniczo pytasz: jeśli już obliczyłem 'np.sin (x)', czy mogę użyć tych informacji, aby uzyskać 'cos (x)' szybciej niż przy ocenie 'np.cos (x)'? – cel

+6

OP odnosi się do faktu, że niektóre biblioteki matematyczne (i sprzęt matematyczny) mają funkcję [sincos] (http://linux.die.net/man/3/sincos), która jednocześnie zwraca zarówno sin & cos of dany argument. Więc nie jest nierozsądne zastanawianie się, czy numpy może to zrobić, IMO. –

Odpowiedz

0

Można skorzystać z tego, że tan (x) zawiera zarówno funkcję sin (x), jak i cos (x). Więc możesz użyć tan (x) i pobrać cos (x) ans sin (x) używając wspólnej funkcji transformacji.

+1

Jak uzyskać prawidłowe informacje o znaku? Czy właśnie sprawdzasz, który kwadrant x jest? –

+0

Bardzo dobrze, przeoczyłem, że to również traci informacje o znaku ... jeśli muszę odzyskać kwadrant kąta, mogę po prostu użyć alternatywnej metody w moim oryginalnym poście. Problem pozostaje; jak szybko określić kwadrant wszystkich elementów w tablicy? – rylirk

+0

odzyskiwanie znaku straciłem przewagę tego tecnique, przypuszczam, że – vathek

0
def cosfromsin(x,sinx): 
    cosx=absolute((1-sinx**2)**0.5) 
    signx=sign(((x-pi/2)%(2*pi))-pi) 
    return cosx*signx 

a=sin(x) 
b=cosfromsin(x,a) 

Właśnie tak ustaliłem czas i jest o 25% szybszy niż przy użyciu grzechu i cos.

+0

Co właściwie czas? I jak duża była tablica 'x', kiedy ją wyliczyłeś? Kiedy dokonuję wstępnego obliczenia 'sinx' i porównuję czas" cos (x) "i' cosfromsin (x, sinx) ',' cosfromsinx' jest wolniejszy. –

+0

Tak też zrobiłem. Przedmiotem, który przekazałem cos i cos od grzechu była dwuwymiarowa tablica numpy o wymiarach w przybliżeniu 2000 * 1000 – rylirk

+0

To 'cosfromsin (x)', z podanym 'sin (x)' jest wolniejsze ~ 4x niż 'cos (x) 'tutaj również dla takich rozmiarów macierzy (a jeszcze gorzej dla małych). Uwaga: można pominąć słowo 'absolute'. 'signcos = (np.int _ ((x - pi_2) // pi) i 1) * 2 - 1' przyspiesza nieco, ale nadal nie pokona. – kxr

2

Można używać liczb zespolonych i faktu, że e i & middot; φ = cos (φ) + i & middot; sin (φ).

import numpy as np 
from cmath import rect 
nprect = np.vectorize(rect) 

x = np.arange(2 * np.pi, step=0.01) 

c = nprect(1, x) 
a, b = c.imag, c.real 

Używam tutaj sprawę z https://stackoverflow.com/a/27788291/674064 zrobić wersję cmath.rect() że będziemy akceptować i powrócić tablic numpy.

nie zdobyć żadnego przyspieszenie na moim komputerze, ale:

c = nprect(1, x) 
a, b = c.imag, c.real 

trwa około trzy razy więcej czasu (160 μ ów)

a, b = np.sin(x), np.cos(x) 

wziął w moim pomiaru (50,4 μ s).

+1

Tak, próbowałem podobnej metody, ale niestety jest o wiele wolniej – rylirk

0

Czysta wersja numpy pomocą liczb zespolonych, e i φ = cos φ + i sin φ, inspirowane odpowiedź od das-g.

x = np.arange(2 * np.pi, step=0.01) 

eix = np.exp(1j*x) 
cosx, sinx = eix.real, eix.imag 

To szybciej niż nprect, ale wolniej niż sin i cos połączeń:

In [6]: timeit c = nprect(1, x); cosx, sinx = cos(x), sin(x) 
1000 loops, best of 3: 242 us per loop 

In [7]: timeit eix = np.exp(1j*x); cosx, sinx = eix.real, eix.imag 
10000 loops, best of 3: 49.1 us per loop 

In [8]: timeit cosx, sinx = cos(x), sin(x) 
10000 loops, best of 3: 32.7 us per loop 
Powiązane problemy