-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add subsets(collection,Val{k})
#13
Changes from 9 commits
30e03d4
a4d0097
eb8d84d
cc057fd
3e502c7
bf4cd96
210af0e
099283e
c5672d3
08bffa6
e4bb403
8a2c3cf
c9c0219
7b77833
36ff235
f6f554b
eb0adab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -708,6 +708,63 @@ end | |
done(it::Binomial, state::BinomialIterState) = state.done | ||
|
||
|
||
# Iterate over all subsets of a collection with a given *statically* known size | ||
|
||
struct StaticSizeBinomial{K,Container} | ||
xs::Container | ||
end | ||
|
||
iteratorsize(::Type{<:StaticSizeBinomial}) = HasLength() | ||
Base.iteratoreltype(::Type{StaticSizeBinomial{K,C}}) where {K,C} = iteratoreltype(C) | ||
|
||
eltype(::Type{StaticSizeBinomial{K,C}}) where {K,C} = NTuple{K,eltype(C)} | ||
length(it::StaticSizeBinomial{K,<:Any}) where {K} = binomial(length(it.xs),K) | ||
|
||
subsets(xs,::Val{K}) where {K} = StaticSizeBinomial{K,typeof(xs)}(xs) | ||
|
||
@generated minus1(::Val{A}) where {A} = :(Val{$(A-1)}()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Jameson has said "no" to this in the past. However, you can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replaced
Performance seems to stay the same. Don't really see the problem with the old code, though. |
||
pop(t::NTuple{K,<:Any}) where {K} = ntuple(i->t[i], minus1(Val{K}())) | ||
|
||
function start(it::StaticSizeBinomial{K,<:Any}) where {K} | ||
xs = it.xs | ||
li = ntuple(identity,minus1(Val{K}())) | ||
lx = ntuple(i->xs[i],minus1(Val{K}())) | ||
return lx, li, li[end]+1 | ||
end | ||
|
||
function advance(it::StaticSizeBinomial{K,<:Any}, xx,ii) where {K} | ||
xs = it.xs | ||
lx = pop(xx) | ||
li = pop(ii) | ||
i = ii[end] + 1 | ||
if i > length(xs)-K+length(ii) | ||
lx,li = advance(it,lx,li) | ||
i = li[end]+1 | ||
end | ||
return (lx...,xs[i]),(li...,i) | ||
end | ||
function advance(it::StaticSizeBinomial,x::NTuple{1,<:Any},i::NTuple{1,<:Any}) | ||
xs = it.xs | ||
i = i[end]+1 | ||
return (xs[i],),(i,) | ||
end | ||
|
||
function next(it::StaticSizeBinomial,state) | ||
xs = it.xs | ||
lx,li,i = state | ||
x = (lx...,xs[i]) | ||
|
||
i += 1 | ||
if i > length(xs) | ||
lx,li = advance(it,lx,li) | ||
i = li[end]+1 | ||
end | ||
return x,(lx,li,i) | ||
end | ||
|
||
done(it::StaticSizeBinomial,state) = state[end] > length(it.xs) | ||
|
||
|
||
# nth : return the nth element in a collection | ||
|
||
""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only if the container has length; see the
Subsets
type. Also defineiteratoreltype
as this will only have eltype ifContainer
has eltype.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was following the implementation of
Binomial
, which has the same issues. The point withiteratoreltype
is fair enough and should be changed for all three cases ofsubsets
. All three implementations requirelength(xs)
, though, so allsubsets
iterators have a length whenever they're defined.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems several iterators in this package do not define
iteratoreltype
correctly. So it might be worth opening up another PR to fix this for all.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Binomial doesn't have the same issues, as it only accepts a
Vector
which always has an eltype and length.