Description
Currently, we have
julia> maximum([fill(NaN, 256); missing])
NaN
julia> maximum([fill(NaN, 255); missing])
missing
julia> maximum(x for x in [fill(NaN, 256); missing])
missing
julia> maximum(x for x in [fill(NaN, 255); missing])
missing
julia> max(missing, NaN)
missing
As you can see, maximum
is incompatible with the definition of max
depending on the size of the array. Furthermore, the result changes when processed with the identity iterator transformation.
I think maximum(xs)
should be defined as reduce(max, xs)
semantically. Currently, it is defined as such at the "syntax" level:
Lines 716 to 725 in 13b07fc
However, mapreduce
implementation for max
/min
is not compatible with the mathematical definition of mapreduce
.
There were related discussions on findmax/min and argmax/min (#27613, #35316) and I've been suggesting to define the total orderings compatible with max
/min
and use it to define all the similar functions, at least at the API definition level. I think this is the right direction as otherwise parallelizing these reducers is hard; i.e., we need to express them as folds with an associative operator which requires transitivity in the corresponding comparison. Furthermore, rigorously defining these reducers would let us confidently leverage the commutativity of max
/min
and define efficient maximum(::Diagonal)
etc. #30236.
So, I suggest to:
- Use the mathematically correct definition in
mapreduce(min, ...)
andmapreduce(max, ...)
. - Define the total ordering compatible with
min
(maybe in Add 2-arg versions of findmax/min, argmax/min #35316) and use it inargmin
andfindmin
. (Note:isless
is alreadymax
-compatible)