Opposite of numpy.unwrap

Question:

In Python numpy, there is an unwrap function that:

Unwrap radian phase p by changing absolute jumps greater than discont
to their 2*pi complement along the given axis.

Now, I’d like to do the opposite function. How can I wrap an array of phases? E.g. how to convert all angles to constraint them between -π and π?

The obvious way would be to do something like:

for i, a in enumerate(phases):
    while a < pi:
        a += 2 * pi
    while a > pi:
        a -= 2 * pi
    phases[i] = a

but is there a simpler / faster way?

Asked By: Charles Brunet

||

Answers:

phases = (phases + np.pi) % (2 * np.pi) - np.pi
Answered By: sega_sai
import numpy as np
phases = np.arctan2(np.sin(phases), np.cos(phases))

This works because sin(phases)/cos(phases) == tan(phases). We get back phases (modulo 2π) by using the inverse-tangent function. Mathematically, the inverse-tangent function is multivalued, so in programming languages it is usually defined to return the phase in a fixed interval.

The two-parameter arctangent function, i.e. np.arctan2(numerator, denominator), is the same as the regular arctangent function except that it keeps track of the signs of the numerator and denominator, and therefore is able to return the phase modulo 2π, instead of the regular np.arctan(numerator/denominator) function which is only able to return the phase modulo π. Numpy’s implementation of the arctan2 function is defined to return the phase in the range [-π, +π], which is the range that the OP requested.

Additional explanation: This arctan2 method follows directly from the complex representation, and is entirely mathematically equivalent to:

phases = np.angle(np.exp(1j*phases))

which may be more intuitive. And in fact, numpy’s angle function uses arctan2 behind the scenes to separate the imaginary and real components of the exponential, i.e. the sine and cosine.

Answered By: u55

This answer is a slight variation to sega_sai answer which is:

phases = ( phases + np.pi) % (2 * np.pi ) - np.pi

This maps phases to [-pi, pi) -> which means pi is mapped to -pi

Shown here:

In [27]: phases = np.pi

In [28]: phases = ( phases + np.pi) % (2 * np.pi ) - np.pi

In [29]: print phases
-3.14159265359

Which is perfectly legitimate but if you want a mapping of (-pi, pi] then

Times the input and output of the operation buy -1. Like so:

phases =  (( -phases + np.pi) % (2.0 * np.pi ) - np.pi) * -1.0
Answered By: pev.hall

I’ve implemented something similar to the suggested functions here in my utility library haggis. The function haggis.math.ang_diff_min does exactly what you want. You can set the definition of a full circle manually, which is nice in case you want to use degrees or grads or any other arbitrary angular measure:

 ang_diff_min(phases, 0)
Answered By: Mad Physicist
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.