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
-------------------------------------------------------