Есть ли быстрый способ вернуть Sin и Cos того же значения в Python?
Мне нужно вернуть значения sin и cos для каждого элемента в большом массиве. На данный момент я делаю:
a,b=np.sin(x),np.cos(x)
где x - некоторый большой массив. Мне нужно сохранить информацию знака для каждого результата, поэтому:
a=np.sin(x)
b=(1-a**2)**0.5
не вариант. Есть ли какой-либо более быстрый способ сразу вернуть оба значения sin и cos?
Ответы
Ответ 1
Вы можете использовать комплексные числа и тот факт, что e я & middot; & phi;= cos (& phi;) + я & middot; Sin (& Phi;).
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
Я использую здесь трюк fooobar.com/questions/454566/..., чтобы сделать версию cmath.rect()
, которые будут принимать и возвращать массивы NumPy.
Это не ускоряет работу на моей машине:
c = nprect(1, x)
a, b = c.imag, c.real
занимает примерно в три раза больше времени (160 мкс), что
a, b = np.sin(x), np.cos(x)
взял мое измерение (50,4 м.).
Ответ 2
Вы могли бы воспользоваться тем, что tan (x) содержит как функцию sin (x), так и cos (x). Таким образом, вы можете использовать tan (x) и извлечь cos (x) ans sin (x) с помощью общей функции преобразования.
Ответ 3
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)
Я только что приурочил это, и это примерно на 25% быстрее, чем использование sin и cos.
Ответ 4
Чистая версия numpy через комплексные числа, e я & phi;= cos & phi; + я sin & phi;
вдохновленный ответом das-g.
x = np.arange(2 * np.pi, step=0.01)
eix = np.exp(1j*x)
cosx, sinx = eix.real, eix.imag
Это быстрее, чем nprect
, но все же медленнее, чем sin
и cos
вызывает:
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