argmax
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.
| Code | Input | Output | Description |
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 introx —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)
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")
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}")
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")
largest peak at 120 Hz · plot: figure 9 (1001 points)
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.