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:
<hansl>
set verbose off
set seed 1234
function matrix which(const matrix cond)
r = rows(cond)
c = cols(cond)
scalar n = r*c
ret = selifr(seq(1,n)', vec(cond))
if min(r, c) > 1
# matrix case: return a 2-column matrix
# with row and columns of the elements
# that satisfy the condition
rcoord = 1 + ((ret-1)%r)
ccoord = ceil(ret/r)
ret = rcoord ~ ccoord
endif
return ret
end function
# vector case, return a vector
x = mnormal(2048, 1)
outliers = which(abs(x) .> 3)
print outliers
eval x[outliers]
# matrix case, return a 2-column matrix
A = muniform(5,3)
small = which(A .< 0.2)
print A small
</hansl>
returns
<output>
outliers (6 x 1)
506
553
565
1036
1181
1710
3.0376
3.6543
-4.1870
3.3249
-3.1812
3.1397
A (5 x 3)
0.66637 0.022258 0.35193
0.69651 0.57633 0.11178
0.96863 0.71386 0.96540
0.81544 0.62609 0.71537
0.14030 0.46443 0.63596
small (3 x 2)
5 1
1 2
2 3
</output>
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?
------------------------------------------------------- Riccardo (Jack) Lucchetti Dipartimento di Scienze Economiche e Sociali (DiSES) Università Politecnica delle Marche (formerly known as Università di Ancona) r.lucchetti@univpm.it http://www2.econ.univpm.it/servizi/hpp/lucchetti -------------------------------------------------------