Есть ли быстрый способ вернуть 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