Max of a vector

It is quite strange that the max function cannot work in an intuitive way. I just want the maximum value in a vector.

``````julia> a = [1,2,3]
3-element Vector{Int64}:
1
2
3

julia> max(a)
ERROR: MethodError: no method matching max(::Vector{Int64})

Closest candidates are:
max(::Any, ::Missing)
@ Base missing.jl:137
max(::Any, ::Any)
@ Base operators.jl:467
max(::Any, ::Any, ::Any, ::Any...)
@ Base operators.jl:578
...

Stacktrace:
[1] top-level scope
@ REPL[66]:1
``````

It is ridiculous that max(1,2,3) is ok, but max([1,2,3]) not ok.

``````julia> max(1,2,3)
3

julia> max([1,2,3])
ERROR: MethodError: no method matching max(::Vector{Int64})

Closest candidates are:
max(::Any, ::Missing)
@ Base missing.jl:137
max(::Any, ::Any)
@ Base operators.jl:467
max(::Any, ::Any, ::Any, ::Any...)
@ Base operators.jl:578
...

Stacktrace:
[1] top-level scope
@ REPL[68]:1
``````
``````julia> maximum([1,2,3])
3
``````
18 Likes

As ever, the help is your friend:

``````help?> max

max(x, y, ...)

Return the maximum of the arguments (with respect to isless). See also the maximum function to take the maximum element from a collection.
``````
20 Likes

I think itâs best to not use language like this. The matter has been considered and discussed several times, for example:

12 Likes

`max([1,2,3]...) # OK`

1 Like

interesting! what is the mechanism?

Now I understand how `max` and `maximum` are different and be fluent to functional programming-reduction, but I couldnât get that point when I was new to julia too.

Actually, `max([1,2,3]...)`=`max(1,2,3)` and `maximum([1,2,3])` are both acceptable to newbie if there is only one way. The real problem is , âWhy julia has two max function?â.

Imagine that a guy from python or matlab yesterday, but `max([1,2,3])` raises error again and again, about 1 hour. He never know why `max` doesnât work, and feel very annoying. But if there was no `max`, he would look for `maximum` in 30 second and be happy. They canât consider the existence of `maximum` because of `max`. Nobody thinks âThis is `max`, but I canât use it, then there is other function like `max` with other name.â.

At least, the existence of `max` and `maximum` is not intuive to strangers.

6 Likes

The Julia REPL is your best friend.

For `max`, it also suggests looking at `maximum`:

``````help?> max
search: max maximum maximum! maxintfloat argmax eigmax RowMaximum typemax findmax findmax! Cintmax_t floatmax Cuintmax_t Matrix minmax tf_matrix BitMatrix macroexpand @macroexpand

max(x, y, ...)

Return the maximum of the arguments (with respect to isless).
See also the maximum function to take the maximum element from a collection.
``````

And for the splatting:

``````help?> ...
search: ...

...

The "splat" operator, ..., represents a sequence of arguments. ... can be used in function definitions, to indicate that the function accepts an arbitrary number of arguments. ...
can also be used to apply a function to a sequence of arguments.
``````
1 Like

`reduce(max, x)` is equivalent to `maximum(x)`.

`max` compares varargs and returen the maximal element.

``````4 = max(1,4,1,2)
``````

But vector has no proper order, so `max([1,4,1,2])` is nonsense.

`reduce` is a higher-order function. It works like

``````max(x[1], max(x[2], ..., max(x[end-1], x[end])...))
``````

, taking `max` fuction as the first argument.

So, `max` and `maximum` is different. But I know how you feel. Welcome to julia, my friend.

1 Like

My two cents: there is here a trade off between elegant implementation and usability.
The points to have separate max/maximum functions relates to how Julia internally treat broadcast, multiple dispatch, etc. Having a single function would make the Julia source code look much more a dirty, overly patched specific implementation for this.
However for a novice Julia user, having this distinction is dramatic.
For how much it is in the doc, this looks to novices like âwhatâs the hell is wrong with this complicated language?ââŚ not really user friendlyâŚ

1 Like

For me more confusing is always that NumPy has exactly the other convention.

That being said, I think an error in the `max` or `maximum` function has not stopped anyone from learning a new language.

``````In [5]: np.maximum(1,2)
Out[5]: 2

In [6]: np.max(np.array([1,2,3]))
Out[6]: 3

In [7]: np.max(1,2)
---------------------------------------------------------------------------
AxisError                                 Traceback (most recent call last)
Cell In[7], line 1
----> 1 np.max(1,2)

File <__array_function__ internals>:200, in amax(*args, **kwargs)

2703 @array_function_dispatch(_amax_dispatcher)
2704 def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
2705          where=np._NoValue):
2706     """
2707     Return the maximum of an array or maximum along an axis.
2708
(...)
2818     5
2819     """
-> 2820     return _wrapreduction(a, np.maximum, 'max', axis, None, out,
2821                           keepdims=keepdims, initial=initial, where=where)

83         else:
84             return reduction(axis=axis, out=out, **passkwargs)
---> 86 return ufunc.reduce(obj, axis, dtype, out, **passkwargs)

AxisError: axis 2 is out of bounds for array of dimension 0

In [8]: np.maximum(np.array([1,2,3]))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[8], line 1
----> 1 np.maximum(np.array([1,2,3]))

TypeError: maximum() takes from 2 to 3 positional arguments but 1 were given

``````
6 Likes

Oh, please, do not suggest thatâŚ

@jiang_ming_zhang , yes there are these two functions. Use and abuse os the REPL help, and feel free to ask anything here, we are glad to help. I would just suggest not being dismissive in your questions. Many of the difficulties you are experiencing are result from tradeoffs that were discussed to exhaustion, so there are good reasons for the language work as it does. In some aspects, these tradeoffs make Julia appear less friendly than other languages, thatâs true. On other aspects is the opposite. At the end, after some experience with Julia, youâll know if the tradeoffs are to your benefit or not. But one needs to start open minded and not expect the language to be necessarily similar to what one is experienced in.

9 Likes

For small arrays should be fine? Some related warning here.

Even for small arrays you have dynamic dispatch. (As opposed to tuples.) Of course, if you have lots of few-element arrays in performance-critical code then you might want to re-think your code structure anyway.

But itâs better (faster, cleaner, more idiomatic) to use the `maximum` function to find the maximum element of a collection. Thatâs what itâs there for.

5 Likes
``````julia> max(a)
ERROR: MethodError: no method matching max(::Vector{Int64})
Finding the minimum or maximum element of an array is performed with `minimum` and `maximum` respectively.
``````
30 Likes

While Python itself uses `max` for both multi-arguments and lists.

1 Like

Julia is a lot more consistent, generic and general than Matlab and this is a pretty good example of that. Letâs look at what Matlab has for `max`âthe core âmethodsâ ignoring weird flags are these:

• `M = max(A)`
• `M = max(A,[],"all")`
• `M = max(A,[],dim)`
• `M = max(A,[],vecdim)`
• `C = max(A,B)`

Even just the first âmethodâ is actually a pretty wild amalgam of behaviors. To quote:

• If `A` is a vector, then `max(A)` returns the maximum of `A`.
• If `A` is a matrix, then `max(A)` is a row vector containing the maximum value of each column of `A`.
• If `A` is a multidimensional array, then `max(A)` operates along the first dimension of `A` whose size is greater than `1`, treating the elements as vectors. The size of `M` in this dimension becomes `1`, while the sizes of all other dimensions remain the same as in `A`. If `A` is an empty array whose first dimension has zero length, then `M` is an empty array with the same size as `A`.
• If `A` is a table or timetable, then `max(A)` returns a one-row table containing the maximum of each variable.

Uhh, what? Is there, like, a function that just gives me the maximum value of an array, regardless of how many dimensions it has? Ah, ok, there it is, itâs the next methodâthe delightfully named `max(A,[],"all")` method. Iâm really seeing everyoneâs point hereâwriting `max(A,[],"all")` really is much nicer than `maximum(A)`. Iâm kidding, of course, thatâs awful, but that is how `maximum` is spelled in Matlab.

Ok, what if we come at it from the other end and compare Juliaâs `max` with Matlabâs? Matlab only documents supporting pairwise `max(A, B)` not n-ary `max(A, B, CâŚ)` like Julia. Also, it assumes that `A` and `B` are some kind of array and you want to do an elementwise `max` operation. Thatâs fine for Matlabâs world view, but what if you have objects that arenât arrays? Shocking concept, I know, but in that case, you might want to compare `n` values using something besides elementwise scalar comparison. For example, itâs often useful to compare arrays or tuples as objects themselves using lexicographical ordering. In fact, this is what Julia does when you apply `max` to arrays:

``````julia> max([1,2,3], [2,3], [])
2-element Vector{Int64}:
2
3
``````

This can be confusing to Matlab users, but itâs a very useful general programming behavior and is similar to how strings work:

``````julia> max("apple", "zoo", "cat")
"zoo"
``````

Of course Matlab only got strings in 2016, so that was hardly a consideration for them, but Julia has had them from the start. In Julia, if you want to do elementwise `max` you use broadcasting:

``````julia> max.([1,2,3],[3,2,1])
3-element Vector{Int64}:
3
2
3
``````

Give the existence of generic n-ary max in Julia, people wanting `max([1, 3, 2])` to return `3` should consider that a general n-ary `max` should actually just return its argument when called with a single argument, i.e. `max([1, 3, 2])` should return its argument, which is `[1, 3, 2]`. We donât actually define a 1-ary `max` because it would be too much of a potential footgun for unsuspecting Matlab refugees, but thatâs what the method should do if it existed.

Anyway, I too find it slightly annoying when I occasionally forget and try to do `max(v)` and it doesnât work, but you should keep in mind that Matlabâs `max` function is a byzantine mess and that the since `max` and `maximum` are fundamentally different concepts, any attempt to fuse them in a language that wants to be consistent, general and generic is bound to end badly.

26 Likes

To be fair, MATLAB started at the end of the 70âs and functions like `max` had to be compatible with the original design since then. Basing everything on 2-d matrices (multi-dimensional came later) was great compared to FORTRAN 77, we thought at that time. `max(max(A))` would return the maximum element over the whole matrix, I believe.

To get also the index of the maximum element in Matlab the same function `max`

``````[m, idx] = max(A)
``````

is used, while in Julia another function `findmax` needs to be remembered.

5 Likes

`argmax` is also possible and very easy to remember since this is the conventional mathematical notation

1 Like