-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify that clip() behavior is undefined when min or max is outside the bounds of x #814
base: main
Are you sure you want to change the base?
Conversation
…the bounds of x As discussed in today's consortium meeting. See the discussion at numpy/numpy#24976.
@asmeurer You opened this PR, but, based on your comments in numpy/numpy#24976 (comment), it is not clear whether you still support making this change. Are you okay with this PR moving forward, assuming that the current standardized behavior remains the same (i.e., no type promotion)? |
Yes, I think this text is especially important given that there is no promotion. If there were promotion this text would serve no purpose, because x would just promote to the common data type and there would be no "out-of-bounds" values. |
I find another corner case that seems not elaborated by the spec. Suppose x is float32, min and max are float64, min < max, but min and max are so close together that they are between two adjacent float32 numbers. Then there is no float32 number whose value is between min and max. The spec doesn’t specify the behavior in this case. Maybe this and the case min > max could be combined into one rule: ”If there exists no element in the data type of I’d also like to take the chance to try clarify the precise meaning of “clamp … x to the range [min, max]”, which seems a bit vague to me. Something like the following might be helpful: ”If the value of min and max are exactly representable by the data type of x and min <= max, then clip(x, min, max) has the same value as maximum(minimum(x, max), min) and the same type as x.” If this definition is deemed undesirable because some implementation imposed a stricter requirement, the following more strict version might help: ”If min and max have the same data type as x and min <= max, then clip(x, min, max) is equivalent to maximum(minimum(x, max), min). Otherwise, the behavior is implementation defined.” Btw, the parameter doc of |
The more general issue with a min/max float64 is that rounding might work against you when downcasting to float32. This does not require
Only defining |
The referenced numpy issue is an interesting one. It shows that Array API conformant semantics cannot be implemented by promotion followed by downcasting. A general definition of clip that is consistent with the currently proposed semantics could be the following:
In math notation, this becomes This definition consistently accounts for any mixture of data type. It is certainly implementable, but since some implementations already impose a stricter requirement on the input types, it may not be suitable for a standard. That’s why I proposed two more restrictive versions in the previous comment, one assuming min and max are representable in T, and one assuming min and max have the type T. |
As a general principle, yes, but If we wanted to allow type promotion wiggle room for some libraries while also allowing other libraries to make the reasonable choice of raising an exception for undefined behavior, we could limit portable Were we to circumscribe portable behavior, this would require downstream libraries building on the Array API to be explicit about what behavior they want (e.g., by wrapping |
As discussed in today's consortium meeting.
See the discussion at numpy/numpy#24976.