Skip to content

Commit

Permalink
Merge pull request #19 from spencerlyon2/julia-0.4
Browse files Browse the repository at this point in the history
purge 0.4 base methods from this package
  • Loading branch information
jiahao committed May 4, 2016
2 parents 69265d0 + 9f4958b commit 92f47e4
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 200 deletions.
11 changes: 0 additions & 11 deletions src/combinations.jl
Expand Up @@ -36,17 +36,6 @@ length(c::Combinations) = binomial(length(c.a),c.t)

eltype{T}(::Type{Combinations{T}}) = Vector{eltype(T)}

"Generate all combinations of `n` elements from an indexable object. Because the number of combinations can be very large, this function returns an iterator object. Use `collect(combinations(array,n))` to get an array of all combinations.
"
function combinations(a, t::Integer)
if t < 0
# generate 0 combinations for negative argument
t = length(a)+1
end
Combinations(a, t)
end


"""
generate combinations of all orders, chaining of order iterators is eager,
but sequence at each order is lazy
Expand Down
20 changes: 0 additions & 20 deletions src/factorials.jl
Expand Up @@ -2,7 +2,6 @@

export
derangement,
factorial,
subfactorial,
doublefactorial,
hyperfactorial,
Expand All @@ -11,23 +10,6 @@ export
primorial,
multinomial

import Base: factorial

"computes n!/k!"
function factorial{T<:Integer}(n::T, k::T)
if k < 0 || n < 0 || k > n
throw(DomainError())
end
f = one(T)
while n > k
f = Base.checked_mul(f,n)
n -= 1
end
return f
end
factorial(n::Integer, k::Integer) = factorial(promote(n, k)...)


"The number of permutations of n with no fixed points (subfactorial)"
function derangement(sn::Integer)
n = BigInt(sn)
Expand Down Expand Up @@ -78,5 +60,3 @@ function multinomial(k...)
end
result
end


69 changes: 0 additions & 69 deletions src/partitions.jl
Expand Up @@ -20,11 +20,6 @@ start(p::IntegerPartitions) = Int[]
done(p::IntegerPartitions, xs) = length(xs) == p.n
next(p::IntegerPartitions, xs) = (xs = nextpartition(p.n,xs); (xs,xs))

"""
Generate all integer arrays that sum to `n`. Because the number of partitions can be very large, this function returns an iterator object. Use `collect(partitions(n))` to get an array of all partitions. The number of partitions to generate can be efficiently computed using `length(partitions(n))`.
"""
partitions(n::Integer) = IntegerPartitions(n)



function nextpartition(n, as)
Expand Down Expand Up @@ -87,11 +82,6 @@ end

length(f::FixedPartitions) = npartitions(f.n,f.m)

"""
Generate all arrays of `m` integers that sum to `n`. Because the number of partitions can be very large, this function returns an iterator object. Use `collect(partitions(n,m))` to get an array of all partitions. The number of partitions to generate can be efficiently computed using `length(partitions(n,m))`.
"""
partitions(n::Integer, m::Integer) = n >= 1 && m >= 1 ? FixedPartitions(n,m) : throw(DomainError())

start(f::FixedPartitions) = Int[]
function done(f::FixedPartitions, s::Vector{Int})
f.m <= f.n || return true
Expand Down Expand Up @@ -152,11 +142,6 @@ end

length(p::SetPartitions) = nsetpartitions(length(p.s))

"""
Generate all set partitions of the elements of an array, represented as arrays of arrays. Because the number of partitions can be very large, this function returns an iterator object. Use `collect(partitions(array))` to get an array of all partitions. The number of partitions to generate can be efficiently computed using `length(partitions(array))`.
"""
partitions(s::AbstractVector) = SetPartitions(s)

start(p::SetPartitions) = (n = length(p.s); (zeros(Int32, n), ones(Int32, n-1), n, 1))
done(p::SetPartitions, s) = s[1][1] > 0
next(p::SetPartitions, s) = nextsetpartition(p.s, s...)
Expand Down Expand Up @@ -222,11 +207,6 @@ end

length(p::FixedSetPartitions) = nfixedsetpartitions(length(p.s),p.m)

"""
Generate all set partitions of the elements of an array into exactly m subsets, represented as arrays of arrays. Because the number of partitions can be very large, this function returns an iterator object. Use `collect(partitions(array,m))` to get an array of all partitions. The number of partitions into m subsets is equal to the Stirling number of the second kind and can be efficiently computed using `length(partitions(array,m))`.
"""
partitions(s::AbstractVector,m::Int) = length(s) >= 1 && m >= 1 ? FixedSetPartitions(s,m) : throw(DomainError())

function start(p::FixedSetPartitions)
n = length(p.s)
m = p.m
Expand Down Expand Up @@ -343,52 +323,6 @@ end
# return Int(best) # could overflow, but best to have predictable return type
#end

doc"""
Previous integer not greater than `n` that can be written as $\prod k_i^{p_i}$ for integers $p_1$, $p_2$, etc.
For a list of integers i1, i2, i3, find the largest
i1^n1 * i2^n2 * i3^n3 <= x
for integer n1, n2, n3
"""
function prevprod(a::Vector{Int}, x)
if x > typemax(Int)
throw(ArgumentError("unsafe for x > typemax(Int), got $x"))
end
k = length(a)
v = ones(Int, k) # current value of each counter
mx = [nextpow(ai,x) for ai in a] # allow each counter to exceed p (sentinel)
first = Int(prevpow(a[1], x)) # start at best case in first factor
v[1] = first
p::widen(Int) = first
best = p
icarry = 1

while v[end] < mx[end]
while p <= x
best = p > best ? p : best
p *= a[1]
v[1] *= a[1]
end
if p > x
carrytest = true
while carrytest
p = div(p, v[icarry])
v[icarry] = 1
icarry += 1
p *= a[icarry]
v[icarry] *= a[icarry]
carrytest = v[icarry] > mx[icarry] && icarry < k
end
if p <= x
icarry = 1
end
end
end
best = x >= p > best ? p : best
return Int(best)
end


"Lists the partitions of the number n, the order is consistent with GAP"
function integer_partitions(n::Integer)
if n < 0
Expand All @@ -411,8 +345,6 @@ function integer_partitions(n::Integer)
list
end



#Noncrossing partitions

#Produces noncrossing partitions of length n
Expand Down Expand Up @@ -447,4 +379,3 @@ function _ncpart!(a::Int, b::Int, nn::Int,
end
end
end

100 changes: 0 additions & 100 deletions src/permutations.jl
Expand Up @@ -8,7 +8,6 @@ export
parity,
permutations


immutable Permutations{T}
a::T
t::Int
Expand All @@ -18,11 +17,6 @@ eltype{T}(::Type{Permutations{T}}) = Vector{eltype(T)}

length(p::Permutations) = (0 <= p.t <= length(p.a))?factorial(length(p.a), length(p.a)-p.t):0

"""
Generate all permutations of an indexable object. Because the number of permutations can be very large, this function returns an iterator object. Use `collect(permutations(array))` to get an array of all permutations.
"""
permutations(a) = Permutations(a, length(a))

"""
Generate all size t permutations of an indexable object.
"""
Expand Down Expand Up @@ -128,97 +122,3 @@ start(p::MultiSetPermutations) = p.ref
next(p::MultiSetPermutations, s) = nextpermutation(p.m, p.t, s)
done(p::MultiSetPermutations, s) =
!isempty(s) && max(s[1], p.t) > length(p.ref) || (isempty(s) && p.t > 0)



"In-place version of nthperm."
function nthperm!(a::AbstractVector, k::Integer)
k -= 1 # make k 1-indexed
k < 0 && throw(ArgumentError("permutation k must be ≥ 0, got $k"))
n = length(a)
n == 0 && return a
f = factorial(oftype(k, n-1))
for i=1:n-1
j = div(k, f) + 1
k = k % f
f = div(f, n-i)

j = j+i-1
elt = a[j]
for d = j:-1:i+1
a[d] = a[d-1]
end
a[i] = elt
end
a
end

"Compute the kth lexicographic permutation of the vector a."
nthperm(a::AbstractVector, k::Integer) = nthperm!(copy(a),k)

"Return the `k` that generated permutation `p`. Note that `nthperm(nthperm([1:n], k)) == k` for `1 <= k <= factorial(n)`."
function nthperm{T<:Integer}(p::AbstractVector{T})
isperm(p) || throw(ArgumentError("argument is not a permutation"))
k, n = 1, length(p)
for i = 1:n-1
f = factorial(n-i)
for j = i+1:n
k += ifelse(p[j] < p[i], f, 0)
end
end
return k
end


# Parity of permutations

const levicivita_lut = cat(3, [0 0 0; 0 0 1; 0 -1 0],
[0 0 -1; 0 0 0; 1 0 0],
[0 1 0; -1 0 0; 0 0 0])

"""
Levi-Civita symbol of a permutation.
Returns 1 is the permutation is even, -1 if it is odd and 0 otherwise.
The parity is computed by using the fact that a permutation is odd if and
only if the number of even-length cycles is odd.
"""
function levicivita{T<:Integer}(p::AbstractVector{T})
n = length(p)

if n == 3
@inbounds valid = (0 < p[1] <= 3) * (0 < p[2] <= 3) * (0 < p[3] <= 3)
return valid ? levicivita_lut[p[1], p[2], p[3]] : 0
end

todo = trues(n)
first = 1
cycles = flips = 0

while cycles + flips < n
first = findnext(todo, first)
(todo[first] $= true) && return 0
j = p[first]
(0 < j <= n) || return 0
cycles += 1
while j first
(todo[j] $= true) && return 0
j = p[j]
(0 < j <= n) || return 0
flips += 1
end
end

return iseven(flips) ? 1 : -1
end

"""
Computes the parity of a permutation using the levicivita function,
so you can ask iseven(parity(p)). If p is not a permutation throws an error.
"""
function parity{T<:Integer}(p::AbstractVector{T})
epsilon = levicivita(p)
epsilon == 0 && throw(ArgumentError("Not a permutation"))
epsilon == 1 ? 0 : 1
end

0 comments on commit 92f47e4

Please sign in to comment.