Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created March 15, 2017 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vznvzn/6a5c096ecfb5eb4d44431be7acf5dd3e to your computer and use it in GitHub Desktop.
Save vznvzn/6a5c096ecfb5eb4d44431be7acf5dd3e to your computer and use it in GitHub Desktop.
def f2(n)
n = (n * 3 + 1) / 2 while (n.odd?)
n /= 2 while (n.even?)
return n
end
def adv(x)
n1 = n = x['n']
l = [n]
while (n >= n1 && n != 1)
n = f2(n)
l << n
end
x['g1'] = l.size
x['w1'] = x['n'].to_s(2).length
x['h1'] = (x['g1'].to_f / x['w1'] * 50).to_i
return x
end
def next2(z)
l = [z]
p = z['p'] + 1
l << adv({'n'=>z['n'] + 2**p, 'p'=>p})
l << z.merge({'p'=>p})
return l
end
def stat(l)
l = [0] if (l.empty?)
t = t2 = 0
l.each \
{
|x|
t += x
t2 += x ** 2
}
c = l.size
a = t.to_f / c
z = t2.to_f / c - a ** 2
sd = Math.sqrt(z < 0 ? 0 : z)
return a, sd, l.max.to_f, l.min.to_f
end
def range(l, s)
['g', 'w', 'h'].each \
{
|k|
l1 = l.map { |x| x[1]["#{k}1"] }
a, sd, mx, mn = stat(l1)
h = hist(l1)
x = h.max_by { |k, v| v }
s.merge!({"#{k}_a" => a, "#{k}_sd" => sd,
"#{k}_mx" => mx, "#{k}_mn" => mn,
"#{k}_md" => x[0]})
}
end
def out(f, a)
f.puts(a.keys.join("\t")) if (f.size == 0)
f.puts(a.values.join("\t"))
f.flush
end
def next1(x, r)
x = next2(x)
return x if (r.empty?)
['g', 'w', 'h'].each \
{
|k|
x[1][k] = (x[1]["#{k}1"] - r["#{k}_a"]) / r["#{k}_sd"]
}
x[1]['gwh'] = x[1]['g'] + x[1]['w'] + x[1]['h']
x[1]['gw'] = x[1]['g'] + x[1]['w']
x[1]['wh'] = x[1]['w'] + x[1]['h']
x[1]['gh'] = x[1]['g'] + x[1]['h']
return x
end
def plot(fn, c)
exe = "C:\\Program Files (x86)\\gnuplot\\bin\\wgnuplot"
system(exe, "-e", "set terminal png; set output 'data/#{fn}.png'; set colors classic; set title '#{fn}'; #{c}")
end
def plot1(fn, k)
c = "plot 'out.txt' using (column('#{k}_a')):(column('#{k}_sd')) with errorbars,\
'' using (column('#{k}_md')) with line, '' using (column('#{k}_mn')) with line, '' using (column('#{k}_mx')) with line;"
plot(fn, c)
end
def hist(l)
h = {}
l.each \
{
|x|
h[x] = h.fetch(x, 0) + 1
}
return h.sort
end
def opt(c, w, ns)
l1 = []
l2 = []
l1 << next2({'n'=>1, 'p'=>0})
puts('# ' + Time.now.to_s)
t = Time.now.to_i
r = {}
f = File.open('out.txt', 'w')
fn = w.join
c.times \
{
|i|
$stderr.puts([i, sprintf('%.1fm', (Time.now.to_i - t) / 60.0), Time.now.to_s].join("\t")) if (i % 100 == 0)
if ((i + 1) % 100 == 0) then
range(l1, r)
out(f, r)
break if (r['w_a'] > ns)
end
w.rotate!
if (w.first == 'r') then
j = l1.size
else
l1 = l1.sort_by { |x| x[1][w.first].nil? ? 0 : -x[1][w.first] }
j = [100, l1.size].min
end
z = l1.delete_at(rand(j))
l1.pop if (l1.size > 1000)
l2 << z[1]
l1 << next1(z[1], r)
l1 << next1(z[2], r)
}
f.close
l3 = l2.select { |x| x['w1'] == ns }
['g', 'w', 'h'].each \
{
|k|
out2(k, l2.map { |x| x["#{k}1"] })
out2(k, l3.map { |x| x["#{k}1"] }, '2')
plot1("#{fn}_#{k}", k)
}
plot("#{fn}_x", "plot [0:200][0:500] 'out_h.txt' using 1:2 with line, 'out_w.txt' using 1:2 with line, 'out_g.txt' using 1:2 with line")
plot("#{fn}_x2", "plot 'out_h2.txt' using 1:2 with line, 'out_w2.txt' using 1:2 with impulse, 'out_g2.txt' using 1:2 with line")
end
def out2(k, l, b = '')
h = hist(l)
f = File.open("out_#{k}#{b}.txt", 'w')
h.each { |k, v| f.puts([k, v].join("\t")) }
f.close
end
def run(c, w)
l = opt(10e3.to_i, w, c)
end
c = 40
[['g'], ['h'], ['w'], ['gw'], ['wh'], ['gh'], ['gwh']].each { |x| run(c, x) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment