Qu

where

Builtin index · Core maths

where(mask) or where(cond, a, b)

Input: mask · Output: no output

What it is

One argument mask (a Vec/Mat of booleans, typically produced by a comparison like x < 0) returns a Vec of the 0-based indices where it is true. Three arguments — cond (a boolean mask), a, b (scalars or arrays broadcastable to cond's shape) — instead select elementwise: a's value where cond is true, b's otherwise (NumPy's where(cond, a, b)), returning the same shape as cond.

Overloads

mask can be Vec, Mat, boolean, or scalar; cond can be boolean or scalar; a can be Vec, Mat, or boolean; b can be boolean or scalar.

2 forms. Each carries its own inputs, outputs and worked example — pick the tab for the one you are calling.

CodeInputOutputDescription
result = where(mask)
mask Vec, Mat, boolean, or scalarnot documented yet
mask Vec or Mata Vec/Mat
Indices where the boolean mask (a Vec/Mat) is true, as a Vec — the 1-argument form.

Examples

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

mask = [true, false, true]
print(where(mask))          # [0, 2] -- indices, 1-argument form

print(where(mask, 1, 0))    # [1, 0, 1] -- elementwise pick, 3-argument form

output
[0, 2]
[1, 0, 1]

from core-math

Z = [100 - 20i, 80 - 45i, 50 - 55i, 30 - 35i, 22 - 12i]   # measured impedance

freqs = [0.1, 1, 10, 100, 1000]                          # Hz


fit = rlkk_reconstruct(Z, freqs, lambda = 1e-4) # fit.z, fit.gamma

v = rlkk_validate(Z, freqs, lambda = 1e-3, threshold = 2.0)
if v.valid
    print("consistent within {v.max_residual:.2f}%")
else
    print("bad points: {where(abs(v.residuals) > 2.0)}")
end if
output
consistent within 0.00%

from specialized

freqs = logspace(0, 4, 20)
R = 100
C = 1e-6
w = 2 * pi * freqs
Z = R / (1 + 1j * w * R * C)         # a simple RC impedance, as measured data


fit = rlkk_reconstruct(Z, freqs, lambda=1e-4)     # fit.z, fit.gamma

v = rlkk_validate(Z, freqs, lambda=1e-3, threshold=2.0)
if v.valid
    print("measurement is causal/linear/stable within {v.max_residual}%")
else
    print("bad points: {where(abs(v.residuals) > 2.0)}")
end

nyquist(Z)   # Re(Z) vs -Im(Z), the standard EIS view

output
measurement is causal/linear/stable within 0.013416%
-200 -100 0 100 200 300 400 500 -200 0 200 400 600 800 x=0.21, y=0 x=0.21, y=0 x=0.21, y=0 x=0.21, y=0 x=0.21, y=0 x=0.21, y=0 x=0.21, y=$10^{-9}$ x=0.21, y=$1.1\times10^{-9}$ x=0.21, y=$1.2\times10^{-9}$ x=0.21, y=$1.3\times10^{-9}$ x=0.21, y=$1.4\times10^{-9}$ x=0.21, y=$1.5\times10^{-9}$ x=0.21, y=$1.7\times10^{-9}$ x=0.21, y=$1.8\times10^{-9}$ x=0.21, y=$2\times10^{-9}$ x=0.21, y=$2.1\times10^{-9}$ x=0.21, y=$2.3\times10^{-9}$ x=0.21, y=$2.5\times10^{-9}$ x=0.21, y=$2.7\times10^{-9}$ x=0.21, y=$2.9\times10^{-9}$ x=0.21, y=$3.2\times10^{-9}$ x=0.21, y=$3.4\times10^{-9}$ x=0.21, y=$3.7\times10^{-9}$ x=0.21, y=$4\times10^{-9}$ x=0.21, y=$4.4\times10^{-9}$ x=0.21, y=$4.8\times10^{-9}$ x=0.21, y=$5.2\times10^{-9}$ x=0.21, y=$5.6\times10^{-9}$ x=0.21, y=$6.1\times10^{-9}$ x=0.21, y=$6.6\times10^{-9}$ x=0.21, y=$7.1\times10^{-9}$ x=0.21, y=$7.7\times10^{-9}$ x=0.21, y=$8.4\times10^{-9}$ x=0.21, y=$9.1\times10^{-9}$ x=0.21, y=$9.9\times10^{-9}$ x=0.21, y=$1.1\times10^{-8}$ x=0.21, y=$1.2\times10^{-8}$ x=0.21, y=$1.3\times10^{-8}$ x=0.21, y=$1.4\times10^{-8}$ x=0.21, y=$1.5\times10^{-8}$ x=0.21, y=$1.6\times10^{-8}$ x=0.21, y=$1.7\times10^{-8}$ x=0.21, y=$1.9\times10^{-8}$ x=0.21, y=$2\times10^{-8}$ x=0.21, y=$2.2\times10^{-8}$ x=0.21, y=$2.4\times10^{-8}$ x=0.21, y=$2.6\times10^{-8}$ x=0.21, y=$2.8\times10^{-8}$ x=0.21, y=$3.1\times10^{-8}$ x=0.21, y=$3.3\times10^{-8}$ x=0.21, y=$3.6\times10^{-8}$ x=0.21, y=$3.9\times10^{-8}$ x=0.21, y=$4.2\times10^{-8}$ x=0.21, y=$4.6\times10^{-8}$ x=0.21, y=$5\times10^{-8}$ x=0.21, y=$5.4\times10^{-8}$ x=0.21, y=$5.9\times10^{-8}$ x=0.21, y=$6.4\times10^{-8}$ x=0.21, y=$6.9\times10^{-8}$ x=0.21, y=$7.5\times10^{-8}$ x=0.21, y=$8.1\times10^{-8}$ x=0.21, y=$8.8\times10^{-8}$ x=0.21, y=$9.5\times10^{-8}$ x=0.21, y=$10^{-7}$ x=0.21, y=$1.1\times10^{-7}$ x=0.21, y=$1.2\times10^{-7}$ x=0.21, y=$1.3\times10^{-7}$ x=0.21, y=$1.4\times10^{-7}$ x=0.21, y=$1.5\times10^{-7}$ x=0.21, y=$1.7\times10^{-7}$ x=0.21, y=$1.8\times10^{-7}$ x=0.21, y=$2\times10^{-7}$ x=0.21, y=$2.1\times10^{-7}$ x=0.21, y=$2.3\times10^{-7}$ x=0.21, y=$2.5\times10^{-7}$ x=0.21, y=$2.7\times10^{-7}$ x=0.21, y=$3\times10^{-7}$ x=0.21, y=$3.2\times10^{-7}$ x=0.21, y=$3.5\times10^{-7}$ x=0.21, y=$3.8\times10^{-7}$ x=0.21, y=$4.1\times10^{-7}$ x=0.21, y=$4.4\times10^{-7}$ x=0.21, y=$4.8\times10^{-7}$ x=0.21, y=$5.2\times10^{-7}$ x=0.21, y=$5.7\times10^{-7}$ x=0.21, y=$6.1\times10^{-7}$ x=0.21, y=$6.7\times10^{-7}$ x=0.21, y=$7.2\times10^{-7}$ x=0.21, y=$7.8\times10^{-7}$ x=0.21, y=$8.5\times10^{-7}$ x=0.21, y=$9.2\times10^{-7}$ x=0.21, y=$10^{-6}$ x=0.21, y=$1.1\times10^{-6}$ x=0.21, y=$1.2\times10^{-6}$ x=0.21, y=$1.3\times10^{-6}$ x=0.21, y=$1.4\times10^{-6}$ x=0.21, y=$1.5\times10^{-6}$ x=0.21, y=$1.6\times10^{-6}$ x=0.21, y=$1.8\times10^{-6}$ x=0.21, y=$1.9\times10^{-6}$ x=0.21, y=$2.1\times10^{-6}$ x=0.21, y=$2.2\times10^{-6}$ x=0.21, y=$2.4\times10^{-6}$ x=0.21, y=$2.6\times10^{-6}$ x=0.21, y=$2.9\times10^{-6}$ x=0.21, y=$3.1\times10^{-6}$ x=0.21, y=$3.4\times10^{-6}$ x=0.21, y=$3.6\times10^{-6}$ x=0.21, y=$4\times10^{-6}$ x=0.21, y=$4.3\times10^{-6}$ x=0.21, y=$4.7\times10^{-6}$ x=0.21, y=$5\times10^{-6}$ x=0.21, y=$5.5\times10^{-6}$ x=0.21, y=$5.9\times10^{-6}$ x=0.21, y=$6.4\times10^{-6}$ x=0.21, y=$7\times10^{-6}$ x=0.21, y=$7.6\times10^{-6}$ x=0.21, y=$8.2\times10^{-6}$ x=0.21, y=$8.9\times10^{-6}$ x=0.21, y=$9.6\times10^{-6}$ x=0.21, y=$10^{-5}$ x=0.21, y=$1.1\times10^{-5}$ x=0.21, y=$1.2\times10^{-5}$ x=0.21, y=$1.3\times10^{-5}$ x=0.21, y=$1.4\times10^{-5}$ x=0.21, y=$1.6\times10^{-5}$ x=0.21, y=$1.7\times10^{-5}$ x=0.21, y=$1.8\times10^{-5}$ x=0.21, y=$2\times10^{-5}$ x=0.21, y=$2.2\times10^{-5}$ x=0.21, y=$2.3\times10^{-5}$ x=0.21, y=$2.5\times10^{-5}$ x=0.21, y=$2.8\times10^{-5}$ x=0.21, y=$3\times10^{-5}$ x=0.21, y=$3.2\times10^{-5}$ x=0.21, y=$3.5\times10^{-5}$ x=0.21, y=$3.8\times10^{-5}$ x=0.21, y=$4.1\times10^{-5}$ x=0.21, y=$4.5\times10^{-5}$ x=0.21, y=$4.9\times10^{-5}$ x=0.21, y=$5.3\times10^{-5}$ x=0.21, y=$5.7\times10^{-5}$ x=0.21, y=$6.2\times10^{-5}$ x=0.21, y=$6.7\times10^{-5}$ x=0.21, y=$7.3\times10^{-5}$ x=0.21, y=$7.9\times10^{-5}$ x=0.21, y=$8.6\times10^{-5}$ x=0.21, y=$9.3\times10^{-5}$ x=0.21, y=$10^{-4}$ x=0.21, y=$1.1\times10^{-4}$ x=0.21, y=$1.2\times10^{-4}$ x=0.21, y=$1.3\times10^{-4}$ x=0.21, y=$1.4\times10^{-4}$ x=0.21, y=$1.5\times10^{-4}$ x=0.21, y=$1.6\times10^{-4}$ x=0.21, y=$1.8\times10^{-4}$ x=0.21, y=$1.9\times10^{-4}$ x=0.21, y=$2.1\times10^{-4}$ x=0.21, y=$2.3\times10^{-4}$ x=0.21, y=$2.5\times10^{-4}$ x=0.21, y=$2.7\times10^{-4}$ x=0.21, y=$2.9\times10^{-4}$ x=0.21, y=$3.1\times10^{-4}$ x=0.21, y=$3.4\times10^{-4}$ x=0.21, y=$3.7\times10^{-4}$ x=0.21, y=$4\times10^{-4}$ x=0.21, y=$4.3\times10^{-4}$ x=0.21, y=$4.7\times10^{-4}$ x=0.21, y=$5.1\times10^{-4}$ x=0.21, y=$5.5\times10^{-4}$ x=0.21, y=$6\times10^{-4}$ x=0.21, y=$6.5\times10^{-4}$ x=0.21, y=$7\times10^{-4}$ x=0.21, y=$7.6\times10^{-4}$ x=0.21, y=$8.2\times10^{-4}$ x=0.21, y=$8.9\times10^{-4}$ x=0.21, y=$9.7\times10^{-4}$ x=0.21, y=0.001 x=0.21, y=0.001 x=0.21, y=0.001 x=0.21, y=0.001 x=0.21, y=0.001 x=0.21, y=0.002 x=0.21, y=0.002 x=0.21, y=0.002 x=0.21, y=0.002 x=0.21, y=0.002 x=0.209, y=0.002 x=0.209, y=0.002 x=0.209, y=0.003 x=0.209, y=0.003 x=0.209, y=0.003 x=0.209, y=0.003 x=0.209, y=0.003 x=0.209, y=0.004 x=0.208, y=0.004 x=0.208, y=0.004 x=0.208, y=0.004 x=0.207, y=0.004 x=0.207, y=0.005 x=100, y=0.063 x=100, y=0.102 x=100, y=0.166 x=99.999, y=0.269 x=99.998, y=0.437 x=99.995, y=0.709 x=99.987, y=1.152 x=99.965, y=1.869 x=99.908, y=3.034 x=99.757, y=4.919 x=99.363, y=7.956 x=98.338, y=12.785 x=95.734, y=20.21 x=89.485, y=30.674 x=76.347, y=42.495 x=55.04, y=49.745 x=31.708, y=46.534 x=14.973, y=35.68 x=6.261, y=24.225 x=2.47, y=15.522 Two stationary tones time (s) frequency (Hz)

from signal-processing

CodeInputOutputDescription
result = where(cond, a, b)
cond boolean or scalarThree arguments — cond (a boolean mask), a, b (scalars or arrays broadcastable to cond's shape) — instead select elementwise: a's value where cond is true, b's otherwise (NumPy's where(cond, a, b)), returning the same shape as cond.
a Vec, Mat, or booleanOne argument mask (a Vec/Mat of booleans, typically produced by a comparison like x < 0) returns a Vec of the 0-based indices where it is true.
b boolean or scalarThree arguments — cond (a boolean mask), a, b (scalars or arrays broadcastable to cond's shape) — instead select elementwise: a's value where cond is true, b's otherwise (NumPy's where(cond, a, b)), returning the same shape as cond.
result —
Elementwise selection: a where cond is true, b otherwise (NumPy's where(cond, a, b)) — the 3-argument form, returning cond's shape rather than a list of indices.

Examples

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

mask = [true, false, true]
print(where(mask))          # [0, 2] -- indices, 1-argument form

print(where(mask, 1, 0))    # [1, 0, 1] -- elementwise pick, 3-argument form

output
[0, 2]
[1, 0, 1]

from core-math

## periodic_profile: a burst that recurs every 2 seconds, folded onto one cycle

fs = 200
n = 0:1:1999          # 10 seconds

t = n / fs
x = 0.05*randn(2000, seed=6)
x = x + where((t mod 2.0) < 0.1, 1.0, 0.0)   # a short spike once per 2s cycle

prof = periodic_profile(x, fs, 2.0, 20, stat="mean")
print("periodic_profile bins: {length(prof)}, spike bin mean = {max(prof)}, baseline ~ {prof[10]}")

## hourly_profile: a day/night sinusoid, sampled once per minute over 2 days

fs_h = 1.0/60.0
n_h = 0:1:2879        # 2 days at 1 sample/min

t_h = n_h / fs_h
hour_of_day = (t_h/3600) mod 24
xh = sin(2*pi*hour_of_day/24) + 0.1*randn(2880, seed=7)
hp = hourly_profile(xh, fs_h, stat="mean")
print("hourly_profile: {length(hp)} bins, quietest hour idx = {find_peaks(-hp)[0]}")

## minutely_profile: activity concentrated in the first 5 minutes of each hour

fs_m = 1.0
n_m = 0:1:10799       # 3 hours at 1 Hz

t_m = n_m / fs_m
minute_of_hour = (t_m/60) mod 60
xm = where(minute_of_hour < 5, 1.0, 0.0) + 0.05*randn(10800, seed=8)
mp = minutely_profile(xm, fs_m, stat="mean")
print("minutely_profile: {length(mp)} bins, busiest minute idx = {find_peaks(mp)[0]}")

## daily_profile: weekday/weekend pattern, one sample per hour over 3 weeks

fs_d = 1.0/3600.0
n_d = 0:1:503         # 21 days at 1 sample/hour

t_d = n_d / fs_d
day_of_week = (t_d/86400) mod 7
xd = where(day_of_week < 5, 1.0, 0.0) + 0.05*randn(504, seed=9)   # higher on weekdays

dp = daily_profile(xd, fs_d, stat="mean")
print("daily_profile: {length(dp)} bins (0=day0..6), values = {dp}")

## monthly_profile: an annual cycle, one sample per day over ~2 years

fs_mo = 1.0/86400.0
n_mo = 0:1:729        # 2 years at 1 sample/day

t_mo = n_mo / fs_mo
xmo = sin(2*pi*t_mo/31557600) + 0.05*randn(730, seed=10)
mop = monthly_profile(xmo, fs_mo, stat="mean")
print("monthly_profile: {length(mop)} bins, values = {mop}")
output
periodic_profile bins: 20, spike bin mean = 0.994081, baseline ~ -0.005544
hourly_profile: 24 bins, quietest hour idx = 17
minutely_profile: 60 bins, busiest minute idx = 3
daily_profile: 7 bins (0=day0..6), values = [0.999204, 1.007344, 1.00092, 1.008568, 1.005545, 0.008587, -0.005461]
monthly_profile: 12 bins, values = [0.258528, 0.701187, 0.950701, 0.941434, 0.711217, 0.260041, -0.255472, -0.69034, ... (12 elements)]

from signal-processing

How it works

selection: where(cond) -> indices where the mask is true. find(collection, fnName) — predicate search (§ collections, 2026-08-24), a *different* 2-argument form distinguished by arity (a mask and a (collection, function-name) pair can't be confused): returns the first element for which fnName is truthy, via find_predicate. where keeps its original 1-argument-only meaning — where(xs, "fn") is a clear error rather than silently reinterpreted, since where never meant "search a collection".

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