# Argmax returns wrong value

**URL:** <https://discourse.julialang.org/t/argmax-returns-wrong-value/90645>\
**Category:** General Usage\
**Tags:** question\
**Created:** [November 22, 2022, 2:41pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645 "2022-11-22T14:41:13Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![lukas\_r](https://avatars.discourse-cdn.com/v4/letter/l/f6c823/32.png) [@lukas\_r](https://discourse.julialang.org/u/lukas_r)\
**Post date:** [November 22, 2022, 2:41pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/1 "2022-11-22T14:41:14Z")

</div>

I have an array of n vectors (of varying length) that I am searching for the largest value. For this I first find the vector containing the largest value with argmax(array) and then find the index of that value with argmax(array[vector]). For one array of 6 vectors with values between 4 and 16.75 this reliably works. For another array of 8 Vectors with values between 4.25 and 34 it finds a relatively high value but not the highest overall. The arrays/vectors are only filled with Float64s and the value returned is not NaN.  
Does anyone have an idea why this happens?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [November 22, 2022, 2:45pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/2 "2022-11-22T14:45:50Z")

</div>

can you give an example where it returns incorrect results?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [November 22, 2022, 2:45pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/3 "2022-11-22T14:45:54Z")

</div>

In Julia, arrays are ordered lexicographically… Comparring two arrays will give the largest array in a lexicographic order, not the highest value. The same goes for comparing values in an array of arrays.

```julia
julia> x = [1, 100]; y = [3, 4];

julia> x > y
false

julia> y > x
true

julia> t = [x, y];

julia> argmax(t)
2

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 22, 2022, 3:16pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/4 "2022-11-22T15:16:48Z")

</div>

> [@lukas\_r](#):
>
> For this I first find the vector containing the largest value with argmax(array)

You could use

```julia
x = [1, 100]; y = [3, 4];
t = [x, y];
maxval, ind = findmax(maximum, t)
loc = findfirst(==(maxval), t[ind])

```

---

<div class="post-metadata">

**Author:** ![lukas\_r](https://avatars.discourse-cdn.com/v4/letter/l/f6c823/32.png) [@lukas\_r](https://discourse.julialang.org/u/lukas_r)\
**Post date:** [November 23, 2022, 8:06am UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/5 "2022-11-23T08:06:00Z")

</div>

When the right value is returned my array consists of 6 vectors, containing 30-50 values ranging between 4 and 16.75. When the wrong value is returned the array consists of 8 vectors, containing between 110-118 values between 4.5 and 34. Here argmax finds neither the longest vector (number 2) nor the one containing the highest value (number 8) but instead vector number 6. This contains 115 values with the highest being 32.75

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [November 23, 2022, 8:56am UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/6 "2022-11-23T08:56:37Z")

</div>

Do you have some example code that we can run to reproduce this?

Based on your description I think @pdeffebach have given the reason, though it is would be easier to say for sure with some code to look at.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 23, 2022, 10:08am UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/7 "2022-11-23T10:08:18Z")

</div>

The description of all the different inputs aren’t really that relevant. The point is that this code

> [@lukas\_r](#):
>
> argmax(array)

is wrong. It does not find the vector with the largest element. It doesn’t matter that it returns the desired result occasionally, by pure chance.

You can use `findmax(maximum, array)` instead, as shown in my code example.

---

<div class="post-metadata">

**Author:** ![zamk](https://avatars.discourse-cdn.com/v4/letter/z/ecd19e/32.png) [@zamk](https://discourse.julialang.org/u/zamk)\
**Post date:** [November 23, 2022, 11:10am UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/8 "2022-11-23T11:10:41Z")

</div>

In the documentation `argmax` is defined as:

```julia
  argmax(A; dims) -> indices

  For an array input, return the indices of the maximum elements over the given dimensions. NaN is treated as greater
  than all other values except missing.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> A = [1.0 2; 3 4]
  2×2 Matrix{Float64}:
   1.0 2.0
   3.0 4.0

  julia> argmax(A, dims=1)
  1×2 Matrix{CartesianIndex{2}}:
   CartesianIndex(2, 1) CartesianIndex(2, 2)

  julia> argmax(A, dims=2)
  2×1 Matrix{CartesianIndex{2}}:
   CartesianIndex(1, 2)
   CartesianIndex(2, 2)

```

It returns the maximum elements over given dimensions of an **array** , not array of vectors. If you can shape your vectors in the same length and create a matrix by concatenating them, then you can get the maximum values you are looking for using `argmax`.

---

<div class="post-metadata">

**Author:** ![lukas\_r](https://avatars.discourse-cdn.com/v4/letter/l/f6c823/32.png) [@lukas\_r](https://discourse.julialang.org/u/lukas_r)\
**Post date:** [November 23, 2022, 12:16pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/9 "2022-11-23T12:16:45Z")

</div>

This worked for me, thanks!

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [November 23, 2022, 1:15pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/10 "2022-11-23T13:15:08Z")

</div>

It is always possible to keep things simple (😜) with:

```julia
julia> x = [1, 100]; y = [3, 4];
julia> t = [x, y];
julia> Iterators.flatten(
         Iterators.map(
           (x,y)->Iterators.map(tuple,x,Iterators.repeated(y)),
           Iterators.map(x->Iterators.map(reverse,x),enumerate.(t)),
           Iterators.countfrom(1)
         )
       ) |> maximum
((100, 2), 1)

```

The actual benefit this has is: 1. Not going through one vector twice which `maximum` and `findfirst` can ; 2. This can work if the inputs are iterators.

---

<div class="post-metadata">

**Author:** ![abraunst](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraunst/32/6880_2.png) [@abraunst](https://discourse.julialang.org/u/abraunst)\
**Post date:** [November 23, 2022, 1:31pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/11 "2022-11-23T13:31:32Z")

</div>

What about

```julia
findmax(findmax(y) for y in t)

```

😄

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 23, 2022, 1:52pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/12 "2022-11-23T13:52:00Z")

</div>

> [@Dan](#):
>
> ```julia
> Iterators.flatten(
> Iterators.map(
> (x,y)->Iterators.map(tuple,x,Iterators.repeated(y)),
> Iterators.map(x->Iterators.map(reverse,x),enumerate.(t)),
> Iterators.countfrom(1)
> )
> ) |> maximum
> 
> ```

Seems like a simple loop would be more readable 😉

> [@abraunst](#):
>
> `findmax(findmax(y) for y in t)`

Really elegant 🙂 The only thing is that if two vectors have the same maximum element, it will select the last one, which is, I think, not the most common behaviour. Selecting the first among several equal elements is the norm.

---

<div class="post-metadata">

**Author:** ![abraunst](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraunst/32/6880_2.png) [@abraunst](https://discourse.julialang.org/u/abraunst)\
**Post date:** [November 23, 2022, 2:44pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/13 "2022-11-23T14:44:55Z")

</div>

I think that it will select the one in which the common element appear first, which, admittedly, is even less common behavior 😂

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [November 23, 2022, 2:48pm UTC](https://discourse.julialang.org/t/argmax-returns-wrong-value/90645/14 "2022-11-23T14:48:17Z")

</div>

The following code is not the most efficient, but it illustrates what I would expect as result:

```julia
vv = [[9, 3, 9, 0], [1, 9, 2], [0, -1]]
mx = maximum(reduce(vcat,vv)) # mx = 9
loc = @. findall(==(mx), vv)

# result:
3-element Vector{Vector{Int64}}:
[1, 3]
[2]
[]

```
