where
where(mask)orwhere(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.
| Code | Input | Output | Description |
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
[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
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
measurement is causal/linear/stable within 0.013416%
from signal-processing
| Code | Input | Output | Description |
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
[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}")
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.