-
Notifications
You must be signed in to change notification settings - Fork 36
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
updates to ones, zeros, oneunit and zero to keep consistency to Base #175
Conversation
Codecov Report
@@ Coverage Diff @@
## master #175 +/- ##
==========================================
+ Coverage 92.06% 92.18% +0.11%
==========================================
Files 7 7
Lines 668 678 +10
==========================================
+ Hits 615 625 +10
Misses 53 53
Continue to review full report at Codecov.
|
With `one` deprecated in favor of `oneunit`, the fallback implementation of `ones` would complain about the usage of `one`. This commit specializes on `ones(Gray, args...)` so that it doesn't throw warnings.
This keep consistency to Base, e.g., `zero(0.8) == 0` and `oneunit(0.8) == 1`
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.
Except for UndefVarError: g not defined
, I think there is no problem. I think that the return type of ones(Gray)
should be decided in terms of image processing.
Edit:
Some of the added methods will be unnecessary when one(::Type{<:Gray})
switch to returning 1
. It might be nice to have TODO comments.
and also fixes some dispatch issues on range type
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.
Some of the added methods will be unnecessary when one(::Type{<:Gray}) switch to returning 1
🤔 not very sure which method would become unnecessary here. If you could elaborate more I'm glad to add more comments
@test zero(g) == zero(T) == Gray(zero(T)) | ||
end | ||
|
||
@test_broken one(Gray{Float32}) * g == g * one(Gray{Float32}) == g |
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.
ColorVectorSpaces seems already fixes this, so it not a valid test anymore.
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 test means one(Gray)
should return 1
. Do not remove it now.
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.
Neither Gray{N0f8}(1) * Gray{N0f8}(0.8)
nor 1 * Gray{N0f8}(0.8
are valid without ColorVectorSpaces...
And Gray{N0f8} == 1
is true
The test means one(Gray) should return 1
I'll add one more test for this.
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.
Neither Gray{N0f8}(1) * Gray{N0f8}(0.8) nor 1 * Gray{N0f8}(0.8 are valid without ColorVectorSpaces...
You are right. However, I think the broken test makes sense to indicate that "this is broken" and "one is an identity element".
The latest commit also fixes JuliaGraphics/Colors.jl#369 |
I had assumed that |
and add missing test for `one`
# specialize ones and zeros for Gray type: | ||
# * Base implementation uses `one` instead of `oneunit`; however, `one(Gray)` will return `1` | ||
# * Base implementation use `Array{T}` to initialize the array, however, if we pass | ||
# `Gray`, it gives an abstract eltype `Array{Gray}`, which is inconsistent to `zero(Gray)` |
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.
To be honest, I don't understand what this comment says. I feel the reason is the opposite.
Even though one(Gray)
should return 1
, not so. Thus, one
shows the warning. Isn't this PR a workaround to avoid that warning? If one(Gray)
returns 1
, ones(Gray)
returns an array of Gray(1)
.
Regarding the latter:
julia> zero(AbstractFloat)
0.0
julia> zeros(AbstractFloat)
0-dimensional Array{AbstractFloat,0}:
0.0
Gray{N0f8}
is just a matter of practicality, i.e. speed or memory efficiency.
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 meant to make ones(Gray)
still return an array of Gray(1)
regardless of the fact that one(Gray) === 1
in the future. Did I misunderstand the original reason for the shift?
I think I need to raise zeros(AbstractFloat)
issue at julialang/julia.. My idea is to make the array eltype equals(===
) to its initializer, which makes more sense to me.
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 think I need to raise zeros(AbstractFloat) issue at julialang/julia..
Umm... What is the problem?
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.
That eltype(ones(AbstractFloat)) === typeof(one(AbstractFloat))
should be true (and for zeros
)
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.
Yes. I understand the claim, but I just want to know the reason.
Edit:
ones
should return one
s instead of oneunit
s as the name suggests.
If we follow your claim, ones
should throw an error because of typeof(one(Gray{T}))!== Gray{T}
(in the near future).
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.
Just opened a PR for this JuliaLang/julia#34948
wrt whether ones(Gray{N0f8}, 4, 4)
should return array of N0f8
or Gray{N0f8}
, I'd like to get @timholy involved. My consideration is that ones
is used so widely that we might want to abuse the meaning for image processing purpose.
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.
Definitely, ones(Gray{N0f8}, 4, 4)
should not return an array of N0f8
. Where did the choice come from?
ones(Gray{N0f8}, 2, 2)
--> Gray{N0f8}[? ?
? ?]
--> Gray{N0f8}[one(Gray{N0f8}) one(Gray{N0f8})
one(Gray{N0f8}) one(Gray{N0f8})]
--> Gray{N0f8}[1 1
1 1]
--> Gray{N0f8}[Gray{N0f8}(1) Gray{N0f8}(1)
Gray{N0f8}(1) Gray{N0f8}(1)]
ones(Gray, 2, 2)
--> Gray[? ?
? ?]
--> Gray[one(Gray) one(Gray)
one(Gray) one(Gray)]
--> Gray[1 1
1 1]
--> Gray[convert(Gray, 1) convert(Gray, 1)
convert(Gray, 1) convert(Gray, 1)]
--> Gray[Gray{N0f8}(1) Gray{N0f8}(1)
Gray{N0f8}(1) Gray{N0f8}(1)]
As you know, the array with non-concrete element type has the performance issue. I think your suggestions are good for application specific types. But in general that is a "premature optimization".
|
Since we have different rules for Also, what benefits would I can understand the general rules here but it looks like I'm still keeping confused when using these in the wild; it's very hard to not thinking Said this, I would feel a lot better if |
Let's not include this PR in v0.10 and leave more time to think about it. |
The point is that if Really, |
I believe it's harmless to support
This becomes the most unambiguous solution for me now. |
If we support multiplication here at all. From a standpoint of pure colorimetry I'm not certain that multiplying RGB by anything other than 1 makes sense. (Of course we have to support it in image processing...) |
Originally posted by @timholy in #175 (comment) I think julia> ones(AbstractFloat,2,2)
2×2 Array{AbstractFloat,2}:
1.0 1.0
1.0 1.0 Of course, julia> Base.one(::Type{AbstractFloat}) = 1 # `1` should be a multiplicative identity for `AbstractFloat`, too.
julia> one(AbstractFloat)
1
julia> ones(AbstractFloat, 2,2)
2×2 Array{AbstractFloat,2}:
1.0 1.0
1.0 1.0
julia> Base.one(::Type{AbstractFloat}) = true # I think this is somewhat strange, but ok.
julia> oneunit(AbstractFloat)
1.0
julia> ones(AbstractFloat, 2,2)
2×2 Array{AbstractFloat,2}:
1.0 1.0
1.0 1.0 We can get the same results for concrete types (e.g. Whether |
I'm converging on the following strategy:
|
It looks reasonable to me. I'm sure some people will wonder why ColorTypes doesn't define |
I am beginning to think we need to extend Julia's printing of EDIT: JuliaLang/julia#35094 |
The issues related to this PR have been settled by PR #243. Now, julia> ones(Gray{N0f8}, 4, 4)
4×4 Matrix{Gray{N0f8}}:
1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0
julia> ones(Gray, 4, 4)
4×4 Matrix{Gray}:
Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0)
Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0)
Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0)
Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0) Gray{N0f8}(1.0) |
ones(Gray{N0f8}, 4, 4)
doesn't throw depwarns (closes supportones(::Type{<:AbstractGray}, sz)
#137)oneunit(::Gray)
andzero(::Gray)
valid and keep consistency to Base behavioreltype(zeros(Gray)) == typeof(zero(Gray)) == Gray{N0f8}
(closes promote_rule for Type{Any} Colors.jl#369)There must be some discussion on these in julialang/julia but I can't find a source...