From 9f4958bbe21ae2ea97ce489ec9e84bb19bd1215b Mon Sep 17 00:00:00 2001 From: Spencer Lyon Date: Wed, 4 May 2016 10:49:35 -0400 Subject: [PATCH] purge 0.4 base methods from this package --- src/combinations.jl | 11 ----- src/factorials.jl | 20 --------- src/partitions.jl | 69 ------------------------------ src/permutations.jl | 100 -------------------------------------------- 4 files changed, 200 deletions(-) diff --git a/src/combinations.jl b/src/combinations.jl index 77505aa..8449738 100644 --- a/src/combinations.jl +++ b/src/combinations.jl @@ -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 diff --git a/src/factorials.jl b/src/factorials.jl index 312835f..1d27dea 100644 --- a/src/factorials.jl +++ b/src/factorials.jl @@ -2,7 +2,6 @@ export derangement, - factorial, subfactorial, doublefactorial, hyperfactorial, @@ -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) @@ -78,5 +60,3 @@ function multinomial(k...) end result end - - diff --git a/src/partitions.jl b/src/partitions.jl index af394c4..ee1543a 100644 --- a/src/partitions.jl +++ b/src/partitions.jl @@ -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) @@ -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 @@ -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...) @@ -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 @@ -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 @@ -411,8 +345,6 @@ function integer_partitions(n::Integer) list end - - #Noncrossing partitions #Produces noncrossing partitions of length n @@ -447,4 +379,3 @@ function _ncpart!(a::Int, b::Int, nn::Int, end end end - diff --git a/src/permutations.jl b/src/permutations.jl index a5fe35e..e93c154 100644 --- a/src/permutations.jl +++ b/src/permutations.jl @@ -8,7 +8,6 @@ export parity, permutations - immutable Permutations{T} a::T t::Int @@ -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. """ @@ -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