NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

Thomas
Hi,

I have a proposal for a feature and I hope this is the right place to post this.

The idea is to have a function to map any input angle to the range of [ 0, 2*pi ] or [ - pi, pi ].

There already is a function called 'unwrap' that does the opposite, so I'd suggest calling this function 'wrap'.

Example usage:
# wrap to range [ 0, 2*pi ]
>>> np.wrap([ -2*pi, -pi, 0, 4*pi ])
[0, pi, 0, 2*pi]

There is some ambiguity regarding what the solution should be for the extremes. An example would be an input of 4*pi, as both 0 and 2*pi would be valid mappings.

There has been interest for this topic in the community (see https://stackoverflow.com/questions/15927755/opposite-of-numpy-unwrap).

Similar functions exist for Matlab (see https://de.mathworks.com/help/map/ref/wrapto2pi.html). They solved the ambiguity by mapping "positive multiples of 2*pi map to 2*pi and negative multiples of 2*pi map to 0." for the 0 to 2*pi case.

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

Nathaniel Smith
How would this proposed function compare to using the modulo operator, like 'arr % (2*pi)'?

On Mon, Nov 23, 2020, 16:13 Thomas <[hidden email]> wrote:
Hi,

I have a proposal for a feature and I hope this is the right place to post this.

The idea is to have a function to map any input angle to the range of [ 0, 2*pi ] or [ - pi, pi ].

There already is a function called 'unwrap' that does the opposite, so I'd suggest calling this function 'wrap'.

Example usage:
# wrap to range [ 0, 2*pi ]
>>> np.wrap([ -2*pi, -pi, 0, 4*pi ])
[0, pi, 0, 2*pi]

There is some ambiguity regarding what the solution should be for the extremes. An example would be an input of 4*pi, as both 0 and 2*pi would be valid mappings.

There has been interest for this topic in the community (see https://stackoverflow.com/questions/15927755/opposite-of-numpy-unwrap).

Similar functions exist for Matlab (see https://de.mathworks.com/help/map/ref/wrapto2pi.html). They solved the ambiguity by mapping "positive multiples of 2*pi map to 2*pi and negative multiples of 2*pi map to 0." for the 0 to 2*pi case.
_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

Daniele Nicolodi
On 24/11/2020 02:49, Nathaniel Smith wrote:
> How would this proposed function compare to using the modulo operator,
> like 'arr % (2*pi)'?

I wrote almost the same word bu word reply, before realizing that taking
the modulo looses the sign. The correct operation is slightly more
complex (untested):

def wrap(alpha):
    return (alpha + np.pi) % 2.0 * np.pi - np.pi

However, I don't think there is much value in adding something so
trivial as a function to numpy: I cannot think to any commonly used
algorithm that requires wrapping the phase, and it is going to be an
infinite source of bikesheeding whether the wrapped range should be
[-pi, pi) or (-pi, pi] or (0, 2*pi] or [0, 2*pi)

Cheers,
Dan


> On Mon, Nov 23, 2020, 16:13 Thomas <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi,
>
>     I have a proposal for a feature and I hope this is the right place
>     to post this.
>
>     The idea is to have a function to map any input angle to the range
>     of [ 0, 2*pi ] or [ - pi, pi ].
>
>     There already is a function called 'unwrap' that does the opposite,
>     so I'd suggest calling this function 'wrap'.
>
>     Example usage:
>     # wrap to range [ 0, 2*pi ]
>     >>> np.wrap([ -2*pi, -pi, 0, 4*pi ])
>     [0, pi, 0, 2*pi]
>
>     There is some ambiguity regarding what the solution should be for
>     the extremes. An example would be an input of 4*pi, as both 0 and
>     2*pi would be valid mappings.
>
>     There has been interest for this topic in the community
>     (see https://stackoverflow.com/questions/15927755/opposite-of-numpy-unwrap
>     <https://stackoverflow.com/questions/15927755/opposite-of-numpy-unwrap>).
>
>     Similar functions exist for Matlab
>     (see https://de.mathworks.com/help/map/ref/wrapto2pi.html
>     <https://de.mathworks.com/help/map/ref/wrapto2pi.html>). They solved
>     the ambiguity by mapping "positive multiples of 2*pi map to 2*pi and
>     negative multiples of 2*pi map to 0." for the 0 to 2*pi case.
>     _______________________________________________
>     NumPy-Discussion mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://mail.python.org/mailman/listinfo/numpy-discussion
>     <https://mail.python.org/mailman/listinfo/numpy-discussion>
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> [hidden email]
> https://mail.python.org/mailman/listinfo/numpy-discussion
>

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

Thomas
Like Nathaniel said, it would not improve much when compared to the modulo operator. 

It could handle the edge cases better, but really the biggest benefit would be that it is more convenient.

And as the "unwrap" function already exists, people would expect that and look for a function for the inverse operation (at least I did).

On Tue, 24 Nov 2020 at 09:22, Daniele Nicolodi <[hidden email]> wrote:
On 24/11/2020 02:49, Nathaniel Smith wrote:
> How would this proposed function compare to using the modulo operator,
> like 'arr % (2*pi)'?

I wrote almost the same word bu word reply, before realizing that taking
the modulo looses the sign. The correct operation is slightly more
complex (untested):

def wrap(alpha):
    return (alpha + np.pi) % 2.0 * np.pi - np.pi

However, I don't think there is much value in adding something so
trivial as a function to numpy: I cannot think to any commonly used
algorithm that requires wrapping the phase, and it is going to be an
infinite source of bikesheeding whether the wrapped range should be
[-pi, pi) or (-pi, pi] or (0, 2*pi] or [0, 2*pi)

Cheers,
Dan


> On Mon, Nov 23, 2020, 16:13 Thomas <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi,
>
>     I have a proposal for a feature and I hope this is the right place
>     to post this.
>
>     The idea is to have a function to map any input angle to the range
>     of [ 0, 2*pi ] or [ - pi, pi ].
>
>     There already is a function called 'unwrap' that does the opposite,
>     so I'd suggest calling this function 'wrap'.
>
>     Example usage:
>     # wrap to range [ 0, 2*pi ]
>     >>> np.wrap([ -2*pi, -pi, 0, 4*pi ])
>     [0, pi, 0, 2*pi]
>
>     There is some ambiguity regarding what the solution should be for
>     the extremes. An example would be an input of 4*pi, as both 0 and
>     2*pi would be valid mappings.
>
>     There has been interest for this topic in the community
>     (see https://stackoverflow.com/questions/15927755/opposite-of-numpy-unwrap
>     <https://stackoverflow.com/questions/15927755/opposite-of-numpy-unwrap>).
>
>     Similar functions exist for Matlab
>     (see https://de.mathworks.com/help/map/ref/wrapto2pi.html
>     <https://de.mathworks.com/help/map/ref/wrapto2pi.html>). They solved
>     the ambiguity by mapping "positive multiples of 2*pi map to 2*pi and
>     negative multiples of 2*pi map to 0." for the 0 to 2*pi case.
>     _______________________________________________
>     NumPy-Discussion mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://mail.python.org/mailman/listinfo/numpy-discussion
>     <https://mail.python.org/mailman/listinfo/numpy-discussion>
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> [hidden email]
> https://mail.python.org/mailman/listinfo/numpy-discussion
>

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

Daniele Nicolodi
On 24/11/2020 10:25, Thomas wrote:
> Like Nathaniel said, it would not improve much when compared to the
> modulo operator. 
>
> It could handle the edge cases better, but really the biggest benefit
> would be that it is more convenient.

Which edge cases? Better how?

> And as the "unwrap" function already exists,

The unwrap() function exists because it is not as trivial.

> people would expect that
> and look for a function for the inverse operation (at least I did).

What is your use of a wrap() function? I cannot think of any.

Cheers,
Dan
_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

ralfgommers


On Tue, Nov 24, 2020 at 11:37 AM Daniele Nicolodi <[hidden email]> wrote:
On 24/11/2020 10:25, Thomas wrote:
> Like Nathaniel said, it would not improve much when compared to the
> modulo operator. 
>
> It could handle the edge cases better, but really the biggest benefit
> would be that it is more convenient.

Which edge cases? Better how?

> And as the "unwrap" function already exists,

The unwrap() function exists because it is not as trivial.

I agree, we prefer not to add trivial functions like this. To help those few people that may need this, maybe just add the one-liner Daniele gave to the Notes section of unwrap()?

Cheers,
Ralf



> people would expect that
> and look for a function for the inverse operation (at least I did).

What is your use of a wrap() function? I cannot think of any.

Cheers,
Dan
_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

Thomas
I use my own implementation of the wrap function in kinematics and kinetics (robotics). 
Solutions beyond [0, 2pi] or [-pi, pi] can cause some problems when combined with learning algorithms, so we wrap them.

Interestingly, today I reviewed code for a teammate. He had the exact same problem, 
but did not think much about it and solved it with if-else statements.

But yes, maybe this is too specific and trivial for a Numpy function. 

Thanks for taking the time to look into it!

On Tue, 24 Nov 2020 at 15:47, Ralf Gommers <[hidden email]> wrote:


On Tue, Nov 24, 2020 at 11:37 AM Daniele Nicolodi <[hidden email]> wrote:
On 24/11/2020 10:25, Thomas wrote:
> Like Nathaniel said, it would not improve much when compared to the
> modulo operator. 
>
> It could handle the edge cases better, but really the biggest benefit
> would be that it is more convenient.

Which edge cases? Better how?

> And as the "unwrap" function already exists,

The unwrap() function exists because it is not as trivial.

I agree, we prefer not to add trivial functions like this. To help those few people that may need this, maybe just add the one-liner Daniele gave to the Notes section of unwrap()?

Cheers,
Ralf



> people would expect that
> and look for a function for the inverse operation (at least I did).

What is your use of a wrap() function? I cannot think of any.

Cheers,
Dan
_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: NumPy Feature Request: Function to wrap angles to range [ 0, 2*pi] or [ -pi, pi ]

Eric Moore-11
In reply to this post by Daniele Nicolodi


On Tue, Nov 24, 2020 at 6:38 AM Daniele Nicolodi <[hidden email]> wrote:
On 24/11/2020 10:25, Thomas wrote:
> Like Nathaniel said, it would not improve much when compared to the
> modulo operator. 
>
> It could handle the edge cases better, but really the biggest benefit
> would be that it is more convenient.

Which edge cases? Better how?

> And as the "unwrap" function already exists,

The unwrap() function exists because it is not as trivial.

> people would expect that
> and look for a function for the inverse operation (at least I did).

What is your use of a wrap() function? I cannot think of any.

Cheers,
Dan


For what it’s worth, this kind of range reduction  can be extremely nontrivial depending on the needs of your application.   Look at the efforts needed to ensure that the trigonometric functions give good results. This is discussed in this paper: 

I don’t think that this belongs in Numpy, but it certainly isn’t a one liner. 

Best,

Eric




_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion