Folks,
while revising some old code I stumbled into a function that I'd written a
while back, and I realised this could go into the extra package. Note:
for large input vectors (n > 5) the recursion approach really is much
slower than direct calculation, so there is quite a lot of room for
optimisation.
Opinions?
<hansl>
function matrix choose(const matrix from, scalar h)
# If "from" is a vector with n elements, this function
# returns a matrix whose rows are all the possible subsets
# with h elements; a recursive algorithm is used.
#
# For example: choose({1,2,3}, 2) returns
#
# 1 2
# 1 3
# 2 3
#
# warning: the returned matrix will have n! / (h! * (n-h)!),
# rows, so handle with care.
if (rows(from) > 1 && cols(from) > 1)
s = argname(from)
printf "%s is not a vector\n", strlen(s) ? s : "argument 1"
return {NA}
endif
if h <= 0
ret = {}
elif h == 1
matrix ret = vec(from)
else
ret = {}
n = nelem(from)
loop i = 1 .. (n - h + 1) --quiet
x = from[i]
matrix c = from[i+1: ]
if rows(c) > 0
matrix ret |= x ~ choose(c, h-1)
endif
endloop
endif
return ret
end function
</hansl>
-------------------------------------------------------
Riccardo (Jack) Lucchetti
Dipartimento di Scienze Economiche e Sociali (DiSES)
Università Politecnica delle Marche
(formerly known as Università di Ancona)
r.lucchetti(a)univpm.it
http://www2.econ.univpm.it/servizi/hpp/lucchetti
-------------------------------------------------------