-
Notifications
You must be signed in to change notification settings - Fork 32
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
defines == generically to work on LazySet pairs #604
Conversation
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.
Works like a charm.
@mforets: I leave the merge to you.
Cross-reference: #378. |
@tomerarnon Thanks for the contribution. Would you please add a docstring? We've got some guidelines in this wiki. |
Sure, I can add a docstring. I am noting now however that the previous definition of equals only works for L{N} == L{N} where L and N are the same. So, e.g., comparing a HalfSpace{Int64} with a HalfSpace{Float64} is not covered (still uses the default false definition). I tried to come up with a definition which would allow L{N} == L{M} where only L is the same, but had considerable trouble. The following definition is the best attempt so far, but it too has problems. It works for all of the cases shown, including the potentially problematic case at the end.
Let me know what you think of this as opposed to the other definition. On the one hand it is more general and therefore perhaps more useful. On the other hand perhaps it allows comparisons which are problematic. Likewise, if you can think of a definition which is the best of both worlds, please let me know! There is perhaps something that can be done with checking if the promotion type of the inputs is an abstract or concrete type, etc., and I have not yet gone that route. Whichever the decided behavior, I can note it in the docs. |
Actually, here is a definition which I believe works in all cases without the trouble described earlier:
It first checks to see if the common supertype of the two types is abstract, thereby not allowing comparisons between different types. I believe in v1.0 the function is called |
Hmm I prefer the original option, making it explicit in the new function's signature: function ==(a::LazySet{N}, b::LazySet{N}) where {N}
....
end We can add some approach at a later stage that covers the case of different |
Good!
True. You can use |
Does this mean you prefer the newest version? |
I agree here. @tomerarnon: Do you have this use case that you switch between numeric types? Otherwise I would keep your initial function (sorry). |
It does not. The last version I included returns false if the promotion type of
By contrast, the first version (from the issue) would not feature the piece about the L{M} == L{N} being a valid comparison.
Admittedly, I do not, I just liked the general solution! If you prefer the original one, I can revert to it, and note the restriction in the docstring. |
Indeed, I must have looked at the second version. Then, since the solution is so simple and with no particular overhead, from my side we can go for the new version. A typical Julia user might expect that behavior anyway. julia> 1. == 1f0
true
help?> ==
[...] For example, all numeric types are compared by numeric value, ignoring type. [...] |
Actually, we can have both versions. The first version takes precedence if the type parameters are identical (and this version is faster), while the second version is the fallback option for the less typical case. function ==(X::L, Y::L) where L<:LazySet
return equality_helper(X, Y)
end
function ==(X::LazySet, Y::LazySet)
# if the common supertype of a and b is abstract, they cannot be compared
if Base.isabstract(promote_type(typeof(X), typeof(Y)))
return false
end
return equality_helper(X, Y)
end
@inline function equality_helper(X::LazySet, Y::LazySet)
for f in fieldnames(X)
if getfield(X, f) != getfield(Y, f)
return false
end
end
return true
end |
Sure, I can implement it as you have it there. As for the docs, I think == maybe be intuitive enough not to require all of the mandatory fields from the wiki, let me know your thoughts on the following options. (This is maybe the longest thread over a 13 line pull request ever 😄) I followed the wiki to produce: wiki style
shorter than wiki style
|
I would use
This sentence is not clear to me. Maybe: |
On second thought, one branch or the other compiles away in the == that has the isabstract() check, so actually it should not be slower.
|
I would also give a negative example. Also, please use |
Got it, Made the change. |
Will do.
I am, but it does not show up when I copy-paste to here, interestingly. You prefer the full version of the docstring though, yes? |
Yes, since you already wrote it 😉 |
Did you push the changes already? I do not see them in this PR. |
No, I hadn't yet pushed, I was waiting for your thoughts on the docstring. Now you should see it . |
src/LazySet.jl
Outdated
``` | ||
""" | ||
function ==(X::LazySet, Y::LazySet) | ||
# if the common supertype of a and b is abstract, they cannot be compared |
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.
Sorry, I renamed the variables, but not in the comment 😞
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.
Ha! I hadn't noticed. If you don't mind I'll change them back to a and b to match the doc
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.
okay
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.
Really I was just being lazy 😞
I prefer X and Y too honestly...
Renamed again.
988fce9
to
d141b80
Compare
Almost done! We still need to include in the docs. |
In Julia v0.7: Warning: `fieldnames(v)` is deprecated, use `fieldnames(typeof(v))` instead. |
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.
Thanks for your endurance 😄
Not a problem. As they say, "if you're going to do something, do it right"! Just to note again something I alluded to in the original issue, this catch-all definition is not as fast as a function defined on each type. That is primarily because the for-loop creates variables which are Unions over all the field types in |
@tomerarnon: Feel free to add yourself to the list of contributors. |
No description provided.