Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy converting range of angles from (-Pi, Pi) to (0, 2*Pi)

Tags:

This seems like it would be very straight forward but I can't seem to figure out how to map angles between -Pi and Pi to the range 0 to 2Pi. I tried using np.select but it freezes my program for some reason. I need the angles in this range since they will be used as training data for a neural net which can not output negative numbers.

audio = wav.read('/home/chase/Desktop/ge.wav')[1].astype(np.float32)
audio = np.mean(audio, 1)
audio /= np.max(np.abs(audio))
audio = np.array([np.fft.rfft(audio[i:i + FRAME_SIZE]) for i in range(0, len(audio) - len(audio) % FRAME_SIZE, FRAME_SIZE)])
audio /= FRAME_SIZE
audio_mag = np.abs(audio)
audio_phase = np.angle(audio)

#this line freezes the program
audio_phase = np.select(audio_phase < 0 , 2 * np.pi + audio_phase, audio_phase)

I need the audio

like image 953
chasep255 Avatar asked May 21 '16 01:05

chasep255


People also ask

How do you write pi in Numpy?

Numpy is a scientific computation library in python and has values for a number of numerical constants including pi. You can use numpy. pi or np. pi depending on how you import the library to get the value of pi.

What does NP angle do?

angle() function is used when we want to compute the angle of the complex argument. A complex number is represented by “ x + yi ” where x and y are real number and i= (-1)^1/2 . The angle is calculated by the formula tan-1(x/y).


2 Answers

Here are several different methods complete with timing:

In [1]: import numpy as np; from numpy import linspace, pi

In [2]: N=10000

In [3]: %timeit x=linspace(-pi, pi, N); np.where(x<0 , 2*pi+x, x)
10000 loops, best of 3: 79.1 µs per loop

In [4]: %timeit x=linspace(-pi, pi, N); np.select(x<0 , 2*pi+x, x)
1 loops, best of 3: 354 ms per loop

In [5]: %timeit x=linspace(-pi, pi, N); x[x<0] += 2*pi
10000 loops, best of 3: 82.5 µs per loop

In [6]: %timeit x=linspace(-pi, pi, N); (x + 2*pi)*(x<0) + x*(x>=0)
10000 loops, best of 3: 149 µs per loop

In [7]: %timeit x=linspace(-pi, pi, N); (x + 2*pi)%(2*pi)
10000 loops, best of 3: 192 µs per loop

I find x[x<0] += 2*pi the most readable, but where(x<0, x+2*pi, x) is slightly faster. The select form is by far the slowest.

For comparison, here is the plain linspace function on the same machine:

In [8]: %timeit x=linspace(-pi, pi, N)
10000 loops, best of 3: 35.9 µs per loop

Given that the program is failing on the select and not the far more expensive fft function, you may be running into a low memory condition, with the array paging to disk (both x<0 and 2*pi+x generate arrays, plus you have the original x and the return value created by select). If this is the case, then you may be better off correcting phase frame by frame.

like image 154
Neapolitan Avatar answered Sep 17 '22 19:09

Neapolitan


Let us say you have these angles:

>>> angles = np.linspace(-np.pi, np.pi, 10)
>>> angles
array([-3.14159265, -2.44346095, -1.74532925, -1.04719755, -0.34906585,
    0.34906585,  1.04719755,  1.74532925,  2.44346095,  3.14159265])

There are two possible ways of doing this ...

  1. Use numpy expressions for finding the negative values ...

The ones less than zero should be converted to the right value. Something like this:

>>> (2*np.pi + angles) * (angles < 0) + angles*(angles > 0)
array([ 3.14159265,  3.83972435,  4.53785606,  5.23598776,  5.93411946,
    0.34906585,  1.04719755,  1.74532925,  2.44346095,  3.14159265])

Remember that in numpy, you can do logical tests ... angles < 0 is a boolean array. However, 1*(angles < 0) is a numeric array, where True values are mapped to 1 and False values are mapped to 0. You can combine the two concepts to get your answer.

  1. You can simply recognize that this is a mathematical expression you are trying to solve:

So for that, simply add 2*np.pi to everything and take the mod. This is exactly like finding the "units place", or converting a number into an octal number etc ...

>>> (angles + 2 * np.pi) % (2 * np.pi)
array([ 3.14159265,  3.83972435,  4.53785606,  5.23598776,  5.93411946,
    0.34906585,  1.04719755,  1.74532925,  2.44346095,  3.14159265])

I hope this helps.

like image 40
ssm Avatar answered Sep 18 '22 19:09

ssm