Am 02.03.2026 um 19:04 schrieb Riccardo (Jack) Lucchetti:
From time to time, when writing hansl code, I find myself having to
select parts of a matrix based on some logical condition. In many
cases, selifr/selifc do the job very well, but it's often useful to
keep the indices of the relevant rows/columns. In this cases, it'd be
nice to have a function vaguely like R's which(), possibly adapted to
the matrix case. For example:
...
Of course, as the example above shows, it's quite easy to code this in
hansl, but perhaps this is one of those cases when we want to have
this done in C for maximum efficiency. Thoughts?
Just for fun, below is a variation that I personally find a little more
intuitive. Now you can start your speed comparisons ;-) But seriously,
since no loops are involved or anything, would there really be a
noticeable speed gain of moving this fully to C?
cheers
sven
<hansl>
function matrix where(const matrix cond, bool debug[FALSE])
r = rows(cond)
c = cols(cond)
matrix R = seq(1,r)' ** ones(c)' # could also use mshape
R = selifr(vec(R), vec(cond))
if c>1
matrix C = seq(1,c) ** ones(r)
C = selifr(vec(C), vec(cond))
endif
if debug
print cond
print R
print C
endif
return (r>1 && c>1) ? (R ~ C) : (c==1 ? R : C)
end function
## test
set verbose off
set seed 1234
# scalar / 1x1 case
eval where(3 > 10)
# vector case col, return a vector
x = mnormal(2048)
outliers = where(abs(x) .> 3)
print outliers
eval x[outliers]
# vector case row, return a vector
x = mnormal(2048)'
outliers = where(abs(x) .> 3)
print outliers
eval x[outliers]
# matrix case, return a 2-column matrix
A = muniform(5,3)
small = where(A .< 0.2)
print A small
</hansl>