Qu

argmax

Builtin index · Core maths

result = argmin(x, [on_invalid=])

Input: x, on_invalid · Output: result

What it is

0-based index of the first-occurring minimum/maximum element of x (a scalar, Vec, or Mat/Signal, flattened).

Overloads

One call shape — this function is not overloaded.

CodeInputOutputDescription
result = argmin(x, [on_invalid=])
x scalar, Vec, Mat, or Signal0-based index of the first-occurring minimum/maximum element of x (a scalar, Vec, or Mat/Signal, flattened).
on_invalid optionalon_invalid= ("propagate"/"ignore"/"error", see this section's intro) controls NaN/Inf handling.
on_invalid= —"propagate"/"ignore"/"error", see this section's intro
x —or, under axis=, the original row/column
Returns a scalar Num index. on_invalid= ("propagate"/"ignore"/"error", see this section's intro) controls NaN/Inf handling; under "ignore" the returned index still refers to a position in the original, unfiltered x (or, under axis=, the original row/column), so it can be used to index straight back into the caller's own data. On a Mat, the optional axis= keyword (0 or 1) instead returns the index of the extremum *within* each column or row — a Vec of length cols/rows, each entry an index into that column/row rather than into the flattened matrix.

Examples

From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.

y = [5, 2, 9, 1, 1, 9]
print("argmin(y) = {argmin(y)}, argmax(y) = {argmax(y)}")   # 3, 2 (first tie wins)

output
argmin(y) = 3, argmax(y) = 2

from fundamentals

spectrum = abs(rfft(y))
freqs    = (0 to len(spectrum) - 1) * fs / len(y)
peak     = argmax(spectrum)
print("largest component at {freqs[peak]:.1f} Hz")
output
largest component at 50.0 Hz

from from-zero

n_per_class = 60
c0x = normal(0, 0.6, n_per_class, seed=1)
c0y = normal(0, 0.6, n_per_class, seed=2)
c1x = normal(4, 0.6, n_per_class, seed=3)
c1y = normal(4, 0.6, n_per_class, seed=4)

Xc0 = hstack(reshape(c0x, n_per_class, 1), reshape(c0y, n_per_class, 1))
Xc1 = hstack(reshape(c1x, n_per_class, 1), reshape(c1y, n_per_class, 1))
Xc = vstack(Xc0, Xc1)             # (120, 2)


n = 2 * n_per_class
idx = 0 to n - 1
y = floor(idx / n_per_class)      # 0 for the first 60 rows, 1 for the last 60


function one_hot(labels, rows, k)
    m = zeros(rows, k)
    for i = 0 to rows - 1
        m[i, labels[i]] = 1
    end for
    return m
end function

Y = one_hot(y, n, 2)

net = mlp_classifier(2, [8], 2, seed=42)
trained = net.fit(Xc, Y, epochs=200, lr=0.1, loss="cross_entropy")

function accuracy(model, X, Ytrue, rows)
    logits = model.predict(X)
    correct = 0
    for i = 0 to rows - 1
        if argmax(logits[i, :]) == argmax(Ytrue[i, :]) then
            correct = correct + 1
        end if
    end for
    return correct / rows
end function

acc = accuracy(trained, Xc, Y, n)
print("training accuracy = {acc:.4f}")
output
training accuracy = 1.0000

from quickstart

fs = 2000
t = linspace(0, 1, fs)
x = sin(2 * pi * 120 * t) + 0.4 * sin(2 * pi * 350 * t) + 0.2 * randn(fs, seed = 4)
X = rfft(x)
f = linspace(0, fs / 2, len(X))
print("largest peak at {round(f[argmax(abs(X))], 1)} Hz")
plot(f, mag2db(abs(X)), color = "#4169e1")
xlabel("frequency (Hz)")
ylabel("magnitude (dB)")
title("two tones in noise")
output
largest peak at 120 Hz
· plot: figure 9 (1001 points)
-80 -60 -40 -20 0 0 150 300 450 Magnitude Response Frequency (Hz) Magnitude (dB) -150 -100 -50 0 50 100 150 0 150 300 450 Phase Response Frequency (Hz) Phase (deg) -250 -200 -150 -100 -50 0 0 150 300 450 Group Delay Frequency (Hz) Delay (samples) -120 -80 -40 0 40 10−272 10−204 10−136 10−68 100 x=-0.135, y=0.991 x=-0.135, y=-0.991 x=0.57, y=0.821 x=0.57, y=-0.821 two tones in noise frequency (Hz) magnitude (dB)

from signal-processing

How it works

Index of the extremum WITHIN the row or column, which is what "argmax along an axis" means everywhere else -- on_invalid="ignore" must still land on a position in the ORIGINAL row/column, not a filtered one, same reasoning as arg_extremum_on_invalid's flat-array version. propagate (the default) is untouched from before this feature existed, including its pre-existing quirk: unlike the flat arg_extremum, this inline per-axis scan does NOT skip a leading NaN, so a NaN at the start of a row/column can pin the result to index 0 -- that is "exactly today's behavior", which is what propagate promises to preserve.

From the note above this builtin in the interpreter, where the reasoning was written down as it was built.

See also

argmin — documented in the same entry.