function entropy(pmf, base)
pmf = pmf/sum(pmf)
return sum(pmf.*log(1./pmf)/log(base))
end
entropy(pmf) = entropy(pmf, 2)
avgLength(code, pmf) = sum(map(length, code).*pmf)/sum(pmf)
function blockPmf(pmf1, n, pmfm)
# Input pmf1: the probability vector of single symbols.
# Input pmfm: the probability vector of symbols of block length m
# Output pmfn: the pmf of symbols of block length n
m = floor(log(length(pmfm))/log(length(pmf1)))
pmfn = copy(pmfm)
for k = m+1:n
pmfn_next = Float64[]
for p in pmfn
push!(pmfn_next, p.*pmf1...)
end
pmfn = copy(pmfn_next)
end
return pmfn
end
blockPmf(pmf1, n) = blockPmf(pmf1, n, pmf1)
function minValues(A, r)
# returns the r smallest numbers in A, and also removes the values from the original list
# r should be positive integer
min_vals = Float64[]
idx_list = Int64[]
for i = 1:r
(min, idx) = findmin(A)
append!(idx_list, idx)
deleteat!(A, idx)
append!(min_vals, min)
end
return min_vals, idx_list
end
function testScheme(args...)
if length(args) == 3
(f, base, pmf) = args
code = f(pmf, base)
scale = log(base)/log(2)
elseif length(args) == 2
(f, pmf) = args
base = 2
code = f(pmf)
scale = 1
end
print("---------------------------\n")
print("Testing scheme: ", f, ".\n")
print("pmf: ", pmf, "\n")
print("Code: ", code, ".\n")
pmf = pmf/sum(pmf)
print("The average length: \t", avgLength(code, pmf)*scale, " [bits].\n")
pmf = pmf[pmf .> 0]
print("The entropy of the pmf: ", entropy(pmf), " [bits].\n\n")
end
function testMultiSchemes(fs, bases, pmf)
scales = log(bases)/log(2)
print("---------------------------\n")
print("pmf: ", pmf, "\n")
pmf = pmf[pmf .> 0]
n = length(pmf)
print("The entropy of the pmf: ", entropy(pmf), " [bits].\n\n")
for i in 1:length(fs)
code = fs[i](pmf, bases[i])
print(pmf/sum(pmf), "\n")
print(fs[i],
" w/ base: ", bases[i],
", code: ", code,
", the average length: ", avgLength(code[1:n], pmf)*scales[i], " [bits].\n")
end
end