-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Should we expect floating point indexing to be implemented? #10154
Comments
In more detail, we call I've never really liked this. This is a case where the types can accurately reflect what is actually supported (namely, integers). I wonder how useful it is in practice to be able to index with integer-valued floats, and get an InexactError for non-integer values, which is what we do now. |
cc ApproxFun.jl authors @dlfivefifty @ajt60gaibb any thoughts? |
I can see how this is useful functionality for I don't think this is useful for general types, such as indexing into a tuple. |
However, in the continuous case |
Has the ability to overload |
I like that you can index textures with floats in GLSL and get interpolated values back. But it's probably not justified to put something like this in Base, as it should rather live in an interpolation package. |
|
I agree it's typically better to handle a float index by specifying floor, ceil, etc. at the call site. Much clearer what's going on. |
Is there support for deprecating this behavior for |
@jakebolewski, we could always just deprecate |
That seems to be a reasonable approach. |
If I may: I think this is a bad idea. In many situations, it is very convenient to not worry about types. It is one of the reasons why switching to Julia was easy for me. I started a discussion at Google groups |
Can you give good examples, where this actually hurts? |
I had the same feeling as @cortner, but I failed to find good examples of where it's useful. I'm sure there are valid cases. (And this feature is much less dangerous than automatic rounding conversion from float to int, there is no loss of information here.) |
This change revealed several type in-safeties in my code, where what started as an int became a float: k/2 instead of div(k,2). So I'm in favour. The deprecating of int() at the same time is a bit annoying, but given that it's ambiguous whether it means integer part or round, I'm ok with that. Sent from my iPad
|
Only time I've used this is to select percentiles lazily, e.g.
but the "cure" is |
Well if folks like my proposal to refactor getindex on AbstractArrays (#10525) then one of my reasons for liking this change will go away. As Tim noted, I still think this is a sensible restriction to make, but I'd be open to reconsidering it now. |
As I had posted on julia-users, an edge case shows up when indexing with floats in regions where epsilon > 1: julia> (1:10^17)[1e16:(1e16+5)] #Not the same as indexing with (10^16:10^16+5)
5-element Array{Int64,1}:
10000000000000000
10000000000000000
10000000000000002
10000000000000004
10000000000000004 |
I think it should be easy enough to throw an exception when a conversion is not "safe". |
Re use cases: it occurs e.g. when I compute an index using |
@dlfivefifty : I am not convinced about the type instability. When there is a performance issue then a programmer who actually cares will be able to find it. Julia provides very nice tools to find type instability. |
Probably wasn't much performance impact, but it did bother me that something I called k was becoming a float...it's very unlikely I would have found this otherwise. (More unlikely that it would ever make a difference however..) My feeling is 99% of cases where get index is called with float are unintentional. (I do kinda think down the line there should be a "relaxed" mode where Julia is not so picky though..) Sent from my iPad
|
@cortner If the index doesn't round to itself, sure. However, I don't think it is so easy to tell in the example I gave whether or not that command was intentional or a mistake. Maybe someone forgot to round the entries of the index set. But maybe someone genuinely intended to do precisely that (since you can index into an array with an arbitrary index set). Trying to second-guess a user's intent is a dangerous rabbit hole to go down. |
AFAIK only Matlab/Octave and Mathematica support indexing into an array with a float. Maple, C, Python, Fortran do not. |
For dense arrays, this is not such a big concern since indexing into a |
Once we have COO arrays, I think you should expect to see a lot of integral dimensions outside of the 2^52 range. |
@cortner, @StefanKarpinski why should indexing for arrays be special cased here? Do you think that most users define indexing for all subtypes of In fact, indexing by floating point values is not even consistently defined in julia> A = randn(3,3)
3x3 Array{Float64,2}:
-1.44595 1.07011 2.06128
-0.46673 0.406243 3.70655
-0.564156 0.494642 -0.936865
julia> A[1.0,1.0]
-1.4459545197847976 but for sparse arrays, and much of the julia> SA = sprandn(3,3,1.0)
3x3 sparse matrix with 9 Float64 entries:
[1, 1] = -0.294094
[2, 1] = 0.00830028
[3, 1] = -1.11293
[1, 2] = 0.304284
[2, 2] = -0.786085
[3, 2] = -0.591092
[1, 3] = 0.648532
[2, 3] = 1.72333
[3, 3] = -0.0314884
julia> SA[1.0,1.0]
ERROR: MethodError: `getindex` has no method matching getindex(::Base.SparseMatrix.SparseMatrixCSC{Float64,Int64}, ::Float64, ::Float64)
Closest candidates are:
getindex(::AbstractArray{T,2}, ::Any, ::Any, ::Any, ::Any...)
getindex(::AbstractArray{T,N}, ::Real)
getindex(::Base.SparseMatrix.SparseMatrixCSC{Tv,Ti<:Integer}, ::Integer)
...
julia> Diagonal(A)[1.0,1.0]
ERROR: MethodError: `getindex` has no method matching getindex(::Base.LinAlg.Diagonal{Float64}, ::Float64, ::Float64)
Closest candidates are:
getindex(::AbstractArray{T,2}, ::Any, ::Any, ::Any, ::Any...)
getindex(::AbstractArray{T,N}, ::Real)
getindex(::Base.LinAlg.Diagonal{T}, ::Integer, ::Integer)
... @mbauman work would help here for subtypes of |
To be clear, I'm kind of ambivalent about this. It's annoying how inconsistent this is across all of Base and various packages. I don't think that indexing is an exceptional case – I want a more consistent policy. But to have such a policy, I think we need to have a reason why we draw the line where we do. Currently, it's a very wiggly line. |
For me, the bright line is just that indexing shouldn't use floating-point numbers in addition to allowing integers. The rationale I see is that:
For me, floating point indexing is almost entirely lose-lose. It's kind of cute that it works, but it's not cute enough to justify its existence in the absence of some other compelling rule that would imply it ought to exist. |
I just want some consistency in the interface as well, but I agree with @johnmyleswhite's points which is why I proposed the change. |
|
In the world where floats can be an index to an array, I'm confused about whether If the proponents of that world think it should be an error, then we might as well allow I don't think that's the right way to go, but doesn't it seem like either you'd have both or none? |
@goretkin Currently: julia> Int(3.9)
ERROR: InexactError()
in call at base.jl:36
julia> Int(4.0)
4
julia> Int("4")
ERROR: MethodError: `convert` has no method matching convert(::Type{Int64}, ::ASCIIString) So it's not like float -> int and string -> int aren't treated differently already; "both or none" doesn't sound like a sufficient rule. |
@goretkin |
If BigInt("4") works then so should Int("4")... Sent from my iPhone
|
I just want to say this discussion got the attention I had hoped for and I am very happy with this, even if the developers decide to stick with integer-only indexing. Just to reiterate, the much bigger issue for me is, that it would be great if the Julia developers could bear in mind that the majority of users and potential users (all of Matlab and R!) of the language are not and don't want to be computer scientists. Possibly I am wrong on this particular issue, but I just think decisions like having to write |
I have to say that I agree with all your examples, other than float for getindex 😀 Sent from my iPhone
|
@cortner I've worked mostly using Stata and R doing economics and statistics in academia and business, and I suspect I'm in the minority, R- and Matlab- user-wise, but... I think writing I'm more on the fence about floating point indexing, but I'm mostly bugged by running into libraries implementing it inconsistency, or partially -- I've never actually missed it personally. |
I think having one command that converts both vectors and scalar to a type is convenient for writing functions that work both on scalars and vectors. int(a) is cleaner than isa(a,Vector)?Vector{Int}(a):Int(a) Sent from my iPad
|
Mapping
This is an argument in favor of considering scalars to be container-like. |
@dlfivefifty IMO those are two separate issues -- either we want that behavior for callable things, not just conversion/coercion (in which case |
Interesting discussion here... but I ask, why shouldn't you be able to index by a floating point value (either binary or decimal)? The indices (subscripts) all get encoded in a wonderfully special way 😀 so that "" sorts before everything, then all numbers (including floating point), and then all strings (unless the rule says to treat numbers as strings)... Unicode is also encoded in a very packed format, so that you normally have things sorted by the Unicode code points, but still can have collations where FOO and foo both sort before FOOBAR (case insensitive - but they are still distinct). So, it is quite frequent to have an array with index with subscripts like "-100.234" 0.123e-6 12345. It would be extremely limiting IMO if Julia did not allow for AbstractArrays to be able to handle this... |
#10525 is about to change this, in a way that's easy to make systematic. |
@timholy that will be just what I need, actually, to implement associative arrays... I have to dig into this, will I be able to have an arbitrary number of dimensions? Some customers had many many dimensions (10 or more easily!) |
Yes, you'll be able to have arbitrary dimensions. "Easy & generic" arbitrary dimensions await #10911, but you can "hand-generate" all the methods you need up to some fixed dimensionality. |
@ScottPJones, it sounds like you are thinking of the (already existing) And, yes, a The |
@stevengj I'd want an ordered, multi-dimensional Dict then... also, can Dict's sort numerically? I hadn't thought so... but there is so much I don't yet know in Julia... (I also want a persistent OMD [ordered, multidimensional Dict 😀] I also have to look if Dict's allow any string, including "", as a key... |
@ScottPJones, an |
Actually, an OrderedDict maintains the insertion order of elements. A I started working on a patch to sort OrderedDicts a while ago, but never Cheers, On Sat, Apr 25, 2015 at 6:51 PM, Steven G. Johnson <[email protected]
|
Thanks @kmsquire, I got the two confused. |
@ScottPJones, Please stop giving your resume whenever you're making an argument. Argument from authority is actively counter-productive to having a reasoned debate. Someone who has only been programming for a year could just as easily be right while people who have been programming for decades are wrong. If you can't make a solid argument without falling back on authority, you don't have a good case. Experience is a great resource, but it should provide good examples from which solid arguments can be made, not serve as a replacement for making a compelling case. |
@StefanKarpinski Sorry about that, I was not trying to make an argument from authority, I hate that myself, but rather based on my experience, of real world applications, and the rest of that comment was an attempt to give an example of just what is done where people do want to use sorted floating point keys, coexisting with sorted, collated strings. |
Handling
(get/set)index(::AType, ::FloatingPoint....)
is inconsistently implemented forAbstractArray
subtypes in base and in user defined types for many packages. Should we expect this case be handled when defining(get/set)index
behavior for user defined types? This needs to be documented (or a generic fallback defined), related to #10064.The text was updated successfully, but these errors were encountered: