-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Make StepRangeLen
in operations which may produce zero step
#40320
Conversation
Would it be good to run PkgEval here? I could imagine that some people are implicitly relying on these returning a |
@nanosoldier |
Something went wrong when running your job:
|
Docker hiccup. Let's try again: @nanosoldier |
Your package evaluation job has completed - possible new issues were detected. A full report can be found here. cc @maleadt |
The failures look mostly real. The AbstractFFT failures are interesting, since it looks like this change introduced some numerical instabilities with operations involving floating points with integer ranges. Could we perhaps promote to InfiniteArrays would be good to look into as well, but I am guessing it wouldn't be too hard to fix the breakage on their side. The others mostly look like their tests are just a little to strict and explicitly test the type of a range, so I don't think we need to worry too much about those. |
I think I fixed the AbstractFFTs test, which was producing this:
But now there are other problems... hope nobody is in a rush. |
Any news on this? Not in a rush, but it would be nice to get this into 1.7, since it could be argued that this is really a bugfix. Let me know if there's anything I can help with. |
base/broadcast.jl
Outdated
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::AbstractRange, x::Number) = StepRangeLen(first(r)*x, step(r)*x, length(r)) | ||
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::StepRangeLen{T}, x::Number) where {T} = StepRangeLen{typeof(T(r.ref)*x)}(r.ref*x, r.step*x, length(r), r.offset) | ||
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::LinRange, x::Number) = LinRange(r.start * x, r.stop * x, r.len) | ||
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::OrdinalRange{<:Integer}, x::AbstractFloat) = Base.range_start_step_length(first(r)*x, x, length(r)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last method here handles the case needed for AbstractFFTs tests, above, of float * UnitRange -> range with twiceprecision.
And (-2:2) * 0.0
works because for floats range_start_step_length
does sometimes allow zero step:
julia> Base.range_start_step_length(1.0, 0, 5)
StepRangeLen(1.0, 0.0, 5)
julia> Base.range_start_step_length(1, 0, 5) # goes to 1st method not 4th
ERROR: ArgumentError: step cannot be zero
But probably it could just be OrdinalRange
. Are there other weird cases we should think about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder whether Base.range_start_step_length(1, 0, 5)
should just return a StepRangeLen
. Do you expect that to be too breaking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't thought about it. Was hoping to change as little as possible, focused on calculations that may produce zero step, rather than constructors.
This one is called by range(1, step=0, length=10)
which would otherwise make an integer StepRange. Whereas range(1, 1, length=10)
works, and makes a floating point range. It is a bit weird that some constructors work and some don't, but this isn't changed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, it's probably better not to change this behavior in this PR. Could you just add a short comment here explaining why we can't use range_start_step_length
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, see what you think of 56d9c27
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Let's run PkgEval one more time once tests pass, but otherwise this should be good to go.
@nanosoldier |
Your package evaluation job has completed - possible new issues were detected. A full report can be found here. cc @maleadt |
Besides IdentityRanges:
That ambiguity might be avoided if you modified BlockArrays:
Maybe that's roughly like |
That should be easily fixable on IdentityRanges' side, so I am not too worried about that.
Yeah, it's just explicitly testing the type, so that should be fine as well. |
Pre-1.7 bump? |
Just realized that it might also be good to have a news entry for this, would you mind adding one? Otherwise will merge later if there are no objections. |
Sure. I added something, perhaps too verbose? |
No, looks good. |
This allows calculations with integer ranges leading to zero step to work:
Will this have awful side effects elsewhere?
Note that it does not change how
range
behaves, nor allow you to enter1:0:1
. Many floating point ranges already useStepRangeLen
and hence already allow zero step, it does change their printing to something which parses:Closes #40317. Closes #10391.