Last active
November 27, 2019 17:24
-
-
Save 0/f52c5ccb159d49bd77a0 to your computer and use it in GitHub Desktop.
Some toys in julialang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Anaphoric if. | |
macro aif(ex) | |
@assert (ex.head == :if) "@aif must be applied to an if expression." | |
cond = ex.args[1] | |
ex.args[1] = :(convert(Bool, it)) | |
quote | |
let it = $cond | |
$ex | |
end | |
end | |
end | |
### Examples: | |
for x in [5, 0] | |
@aif if x | |
println("I counted $it things.") | |
else | |
println("I didn't find anything.") | |
end | |
end | |
# I counted 5 things. | |
# I didn't find anything. | |
# Julia lacks this common conversion, so we add it. | |
import Base.convert | |
convert(::Type{Bool}, x::String) = !isempty(x) | |
for x in ["something", ""] | |
@aif if x | |
println("Got $it.") | |
else | |
println("There was nothing.") | |
end | |
end | |
# Got something. | |
# There was nothing. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Base.in, Base.intersect, Base.push!, Base.show, Base.union | |
# Bloom filter. | |
immutable Bloom{k,m} | |
bits::BitVector | |
function Bloom(bits::BitVector) | |
k > 0 || error("Number of hashes must be positive.") | |
m > 0 || error("Number of bits must be positive.") | |
length(bits) != m && error("Length mismatch.") | |
new(bits) | |
end | |
end | |
Bloom(k::Integer, bits::BitVector) = Bloom{k,length(bits)}(bits) | |
Bloom(k::Integer, m) = Bloom(k, falses(m)) | |
function show{k,m}(io::IO, b::Bloom{k,m}) | |
bitstr = join([x ? "#" : " " for x in b.bits]) | |
size = lpad(dec(sum(b.bits)), ndigits(m), " ") | |
print(io, "|$bitstr|($size/$m)") | |
end | |
function hash_indices{k,m}(b::Bloom{k,m}, x) | |
[hash(x, convert(Unsigned, i)) % m + 1 for i in 1:k] | |
end | |
push!(b::Bloom, x) = (b.bits[hash_indices(b, x)] = true; b) | |
in(x, b::Bloom) = all(b.bits[hash_indices(b, x)]) | |
union{k,m}(bs::Bloom{k,m}...) = Bloom(k, |([b.bits for b in bs]...)) | |
intersect{k,m}(bs::Bloom{k,m}...) = Bloom(k, (&)([b.bits for b in bs]...)) | |
### Examples: | |
check(elems, b::Bloom) = filter(x -> x in b, elems) | |
b = Bloom(4, 16) | |
elems = {123 5.5 -5 "a"} | |
println("$b $(check(elems, b))") | |
for x in elems | |
push!(b, x) | |
println("$b $(check(elems, b))") | |
end | |
println(check(1:50, b)) | |
# | |( 0/16) {} | |
# | # ## # |( 4/16) {123} | |
# | # # ## # |( 5/16) {123,5.5} | |
# |# # #### ## |( 8/16) {123,5.5,-5} | |
# |### # #### ## # |(11/16) {123,5.5,-5,"a"} | |
# [11,15,21,23,33,37,39,42,45] | |
bs = {Bloom(4, 16) for _ in 1:3} | |
xss = {[1, 2, 3] [1, 2, 4] [1, 5, 6]} | |
elems = union(xss...) | |
for (b, xs) in zip(bs, xss) | |
for x in xs | |
push!(b, x) | |
end | |
println(" $b $(check(elems, b))") | |
end | |
bu = union(bs...) | |
bi = intersect(bs...) | |
println("U $bu $(check(elems, bu))") | |
println("I $bi $(check(elems, bi))") | |
# | #### # # ## |( 8/16) [1,2,3] | |
# |# ## # ## ## |( 8/16) [1,2,4] | |
# | ### ##### #|( 9/16) [1,5,6] | |
# U |###### # #######|(14/16) [1,2,3,4,5,6] | |
# I | ## # # |( 4/16) [1] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using DataStructures | |
# Markov chain text generator. | |
const start_state = "__START__" | |
function tokenize(filename) | |
open(filename) do stream | |
for line in eachline(stream) | |
for m in eachmatch(r"\S+", line) | |
produce(m.match) | |
end | |
end | |
end | |
end | |
function expand_state(counts) | |
values = String[] | |
for (target, count) in counts | |
for _ in 1:count | |
push!(values, target) | |
end | |
end | |
values | |
end | |
function build_states(tokens) | |
counter = DefaultDict(String, DefaultDict, () -> DefaultDict(String, Int, 0)) | |
cur = start_state | |
for token in tokens | |
counter[cur][token] += 1 | |
cur = token | |
end | |
result = Dict{String,Vector{String}}() | |
for (state, counts) in counter | |
result[state] = expand_state(counts) | |
end | |
result | |
end | |
function walk_states(states) | |
cur = start_state | |
while length(states[cur]) > 0 | |
n = states[cur] | |
r = rand(1:length(n)) | |
cur = n[r] | |
produce(cur) | |
end | |
end | |
function gen_text(source, lim=100) | |
tokens = @task tokenize(source) | |
states = build_states(tokens) | |
walker = @task walk_states(states) | |
join([consume(walker) for _ in 1:lim], " ") | |
end | |
### Examples: | |
using TextWrap | |
# Let's try it on some classics from Project Gutenberg. | |
println_wrapped(gen_text("alice.txt")) | |
println() | |
println_wrapped(gen_text("holmes.txt")) | |
println() | |
println_wrapped(gen_text("aesop.txt")) | |
println() | |
println_wrapped(gen_text("xmas.txt")) | |
println() | |
println_wrapped(gen_text("all.txt")) | |
# CHAPTER I. Down the evening, beautiful garden--how IS his watch out loud. | |
# 'Thinking again?' the rest of the Hatter hurriedly left alone. 'I daresay | |
# it's asleep, I eat cats?' ... | |
# ADVENTURE III. A clump of the name is infinitely the war he found me for us. | |
# Well, he remarked, a policeman, or token before three. ... | |
# The elder woman, ashamed to the theaters without inquiry. I only for | |
# imaginary schemes perished in the heights of the Stag; and firm even the | |
# noise, awoke and cried the Amaranth AN EAGLE made a child. ... | |
# STAVE IV: THE THREE SPIRITS WHEN Scrooge entered poor one away to yield to | |
# follow it. "Thank'ee," said Scrooge, quickening his daughter laughed | |
# heartily, and touched a brazier, round and tumult of himself in the growing | |
# strong in his list. ... | |
# The Buffoon and ourselves, and his actions were always said to say his den to | |
# make fine actor, and lost an advance was loose. He slipped behind him. A | |
# CERTAIN poor ignorant little fancy about a black clay pipe, which it was no | |
# use without a bad taste. Heavy bands which the saucepan of us all. ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Print out all the subtypes of x recursively. | |
function subtypes_rec(x::DataType; depth=0, seen=Set{DataType}()) | |
indent = " "^2depth | |
if x in seen | |
# The type graph is not a tree in Julia, as Any is a subtype of itself, | |
# so we have to be careful about cycles. | |
print_with_color(:red, "$indent$x [cycle]\n") | |
return | |
end | |
push!(seen, x) | |
print_with_color(x.abstract ? :cyan : :bold, "$indent$x\n") | |
for s in subtypes(x) | |
subtypes_rec(s, depth=depth+1, seen=seen) | |
end | |
nothing | |
end | |
### Examples: | |
# You may need to run Julia with --color to see colored text. | |
subtypes_rec(Number) | |
# Number | |
# Complex{T<:Real} | |
# Real | |
# FloatingPoint | |
# BigFloat | |
# ... | |
# Float64 | |
# Integer | |
# BigInt | |
# ... | |
subtypes_rec(Any) | |
# Any | |
# AbstractArray{T,N} | |
# ... | |
# Any [cycle] | |
# Associative{K,V} | |
# Dict{K,V} | |
# ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Base.copy | |
# Velocity Verlet integrator. | |
type State{T<:FloatingPoint} | |
xs::Vector{T} | |
ps::Vector{T} | |
end | |
copy{T}(s::State{T}) = State{T}(copy(s.xs), copy(s.ps)) | |
immutable Universe{T} | |
masses::Vector{T} | |
force::Function | |
state::State{T} | |
end | |
Universe(masses, force, xs, ps) = Universe(masses, force, State(xs, ps)) | |
type Integrator | |
u::Universe | |
dt | |
next_force | |
Integrator(u, dt) = new(u, dt) | |
end | |
# Velocity verlet step. | |
function vvstep(itg::Integrator) | |
u, s = itg.u, itg.u.state | |
fs = isdefined(itg, :next_force) ? itg.next_force : u.force(s.xs) | |
xs_ = s.xs + (itg.dt * s.ps + itg.dt^2 * fs / 2) ./ u.masses | |
itg.next_force = u.force(xs_) | |
ps_ = s.ps + itg.dt * (fs .+ itg.next_force) / 2 | |
s.xs, s.ps = xs_, ps_ | |
end | |
type Trajectory{T} | |
states::Vector{State{T}} | |
next_slot | |
end | |
Trajectory{T}(u::Universe{T}, n::Integer) = Trajectory(Array(State{T}, n), 1) | |
isfull(t::Trajectory) = t.next_slot > length(t.states) | |
function record!(t::Trajectory, s::State) | |
t.states[t.next_slot] = copy(s) | |
t.next_slot += 1 | |
end | |
### Examples: | |
using Winston | |
const dt = 0.05 | |
const colors = ["blue", "green"] | |
# Initial conditions. | |
const xs0 = [1.0, 0.5] | |
const ps0 = [0.0, 0.0] | |
const masses = [2.0, 3.0] | |
const ks = [1.5, 2.0] | |
const k_coupling = 4.0 | |
function harmonic_oscillators(xs) | |
-ks .* xs | |
end | |
function harmonic_oscillators_coupled(xs) | |
-ks .* xs .- k_coupling * [xs[1] - xs[2], xs[2] - xs[1]] | |
end | |
const configs = [ | |
(harmonic_oscillators, 10.0, "harmonic oscillators", "normal"), | |
(harmonic_oscillators_coupled, 100.0, "coupled harmonic oscillators", "coupled"), | |
] | |
for (f, time, title, filename) in configs | |
steps = int(ceil(time / dt)) | |
u = Universe(masses, f, xs0, ps0) | |
itg = Integrator(u, dt) | |
t = Trajectory(u, steps) | |
while !isfull(t) | |
record!(t, u.state) | |
vvstep(itg) | |
end | |
p = FramedPlot(title="Phase space for $title", xlabel="x", ylabel="p") | |
for i in 1:2 | |
c = Curve([s.xs[i] for s in t.states], [s.ps[i] for s in t.states], color=colors[i]) | |
add(p, c) | |
end | |
file(p, "vv_$filename.pdf") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment