Numpy: np.clip with complex input is untested and has odd behavior

Created on 23 Feb 2020  ·  8Comments  ·  Source: numpy/numpy

This came up in https://github.com/pytorch/pytorch/issues/33568. This seems odd:

>>> np.clip([3 + 4.j], -1, 2)                                                                                       
array([2.+0.j])
>>> np.clip([3 + 4.j], -1+1.j, 2+12.j)  # imaginary component goes up                                                                   
array([2.+12.j])
>>> np.clip([1 + 4.j], -1+1.j, 2+12.j)  # imaginary component doesn't go up                                                                             
array([1.+4.j])

The only test for complex input is that it doesn't segfault.

Reasonable behavior could be one of:

  • Clip real and imaginary parts separately
  • Clip absolute value, not changing the phase
    There may be other options. As long as it's documented, I'm not sure it matters much which choice is made.

I don't think this is a very important issue, but it would be nice to at least have the desired behavior documented here.

00 - Bug numpy.core

Most helpful comment

@mruberry, I agreed, in any case I am not even sure anyone had even a use-case for this, which would go a long way to motivate me to put in anything. As one argument to make it a bit less bad, if you ensure that min.real <= max.real and min.imag <= max.imag as opposed to only min <= max, than things are fine (although we currently do not actually ensure this in NumPy).

All 8 comments

The current behavior is to makex = sorted(x) for x = [min, clip(arr, min, max), max], I think.

I doubt it is valuable to break consistency with min, max, sorting here for a non-obvious behaviour choice. Not that we can't do it, but than we should probably also discuss min/max and sorting behaviour...
And if that is to say that an absmin, absmax, and abssort would make sense and basically use that for clipping.
I could be more easily convinced to just giving an error for non-real input.

EDIT: Arguably componentwise clipping actually allows for Erics behaviour, since it is more strict. But just a note, I am not sure I buy it as being useful. The other question is: is there any actual usecase for this at all? One that is not clearer with different code?

Clip real and imaginary parts separately

That would be my first choice.

Clip absolute value, not changing the phase

Could be useful but is more complicated to implement than a simple clip.

The other question is: is there any actual _usecase_ for this at all? One that is not clearer with different code?

That's a good question. I'm not sure. All I know is it shouldn't be so obviously incorrect.

I'm worried about clipping the real and imaginary parts separately. If we have a sorted array, for example, then clipping typically changes the array to have three regions: [min_value, unchanged, max_value]. If we clip the real and imaginary parts of a complex array separately, however, then we will no longer have these separable regions. Instead, values may change even if they don't compare less than the min or greater than the max!

I would also recommend disabling the behavior until there's confidence about what, exactly, clipping a complex number should do. My proposal would be that if c < min_value it's set to min_value, and if c > max_value its set to max_value.

@mruberry, I agreed, in any case I am not even sure anyone had even a use-case for this, which would go a long way to motivate me to put in anything. As one argument to make it a bit less bad, if you ensure that min.real <= max.real and min.imag <= max.imag as opposed to only min <= max, than things are fine (although we currently do not actually ensure this in NumPy).

I'm agreeing with you, too @seberg ;).

I think we're going to disable clipping (we call it clamping) complex inputs in PyTorch for now. Our behavior was inconsistent with NumPy's, anyway.

just reading through this issue, i think that given the lexicographic comparison in numpy, this behavior actually makes sense. if we are deprecating lexicographic comparison though, clip, max and min should also follow. I am assuming that this was the consensus reached here, but I wasn't very sure from the comments and the linked PRs.

Was this page helpful?
0 / 5 - 0 ratings