Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created December 4, 2020 18:21
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/871726f2c5571619655a0304131b3f29 to your computer and use it in GitHub Desktop.
Save vznvzn/871726f2c5571619655a0304131b3f29 to your computer and use it in GitHub Desktop.
def f2(n)
return n.odd? ? (n * 3 + 1) / 2 : n / 2
end
def seq(n)
l = [n]
while (n != 1)
n = f2(n)
l << n
end
return l
end
def outin(fn)
l = (f = File.open(fn)).readlines
f.close
raise if (l.shift.chop != '$dat << eof')
k = l.shift.split
i = l.index("eof\n")
raise if (i.nil?)
l[i..-1] = []
l2 = l.map { |x| Hash[[k, x.split.map { |x| Kernel.eval(x) }].transpose] }
l2.each { |x| x['ns'] = x['ns'].to_s }
$stderr.puts([fn, l2.size].inspect)
return l2
end
def load(l1 = [1])
l = []
l1.each \
{
|i|
l.concat(outin("tmp/gnuplot#{i}-1.cmd"))
}
return l
end
def sample2(l, n)
d = (l.size - 1).to_f / (n - 1)
l2 = []
n.times \
{
|i|
j = (i * d).to_i
l2 << l[j]
}
return l2
end
def len(ns, p)
l = ns.split(p)
l = [] if (l.nil?)
l.shift if (l[0] == '')
return l.map { |x| x.length }
end
def len1(ns)
return len(ns, /0+/)
end
def len0(ns)
return len(ns, /1+/)
end
def len01(ns)
return len1(ns), len0(ns)
end
def e(ns)
return 0 if (ns.empty?)
return len01(ns).flatten.size.to_f / ns.length
end
def d(s)
return 0 if (s.empty?)
c = s.split('').select { |x| x == '1' }.size
d = c.to_f / s.length
return d
end
def midpt(ns)
w2 = ns.length / 4
l = ns.split('')
i = j = 0
while (i < w2 && j < l.size)
i += l[j].to_i
j += 1
end
return j.to_f / ns.length
end
def d1(s)
c = s.split('').select { |x| x == '1' }.size
return c
end
def midpt2(ns)
w2 = d1(ns) / 2
l = ns.split('')
i = j = 0
while (i < w2 && j < l.size)
i += l[j].to_i
j += 1
end
return j.to_f / ns.length
end
def log2(x)
return Math.log(x) / Math.log(2.0)
end
def features(ns)
d = d(ns) - 0.5
e = e(ns) - 0.5
nw = ns.length
nw2 = nw / 2
nshi = ns[0...nw2]
nslo = ns[nw2..-1]
dlo = d(nslo) - 0.5
dhi = d(nshi) - 0.5
elo = e(nslo) - 0.5
ehi = e(nshi) - 0.5
mp1 = midpt(ns) - 0.5
mp2 = midpt2(ns) - 0.5
mx0 = len0(ns).max
mx0 = 0 if (mx0.nil?)
mx1 = len1(ns).max
mx01 = [mx0, mx1].max
mx = log2(log2(ns.to_i(2).to_f))
a0 = avg(len0(ns))
a1 = avg(len1(ns))
a01 = avg(len01(ns).flatten)
return {
"d" => d,
"e" => e,
"ea" => e.abs,
"da" => d.abs,
"dlo" => dlo,
"dhi" => dhi,
"elo" => elo,
"ehi" => ehi,
'mp1' => mp1,
"mp2" => mp2,
'mx0' => mx0.to_f / ns.length,
'mx1' => mx1.to_f / ns.length,
'mx01' => mx01.to_f / ns.length,
'a0' => a0 / ns.length,
'a1' => a1 / ns.length,
'a01' => a01 / ns.length,
'a1m' => a1 / mx,
"nw" => ns.length
}
end
def dataset(l)
return l.map { |x| x.empty? ? {} : features(x['ns']).merge({$k => x[$k], 'cg' => x['cg']}) }
end
def near(x, l, k2 = '', l1 = [])
l.each_with_index \
{
|x1, j|
next if (x == x1)
z = 0
['d', 'e', 'da', 'ea', 'dlo', 'dhi', 'elo', 'ehi', 'mp1', 'mp2',
'mx0', 'mx1', 'mx01', 'a0', 'a1', 'a01', 'a1m'].each \
{
|k1|
k = "#{k1}#{k2}"
z += (x[k] - x1[k1]) ** 2
}
l1 << [z, j]
}
l1.sort_by! { |x| x[0] }
i = 0
i += 1 while (i + 1 < l1.size && l1[i][0] == l1[i + 1][0])
return (0..i).map { |x| l[l1[x][1]].merge({'z' => l1[x][0]}) }
end
def predict(l2, l1)
e1 = 0
l1.each { |x| x['nn'] = []; x.delete('er2') }
ky = $k
l2.each_with_index \
{
|x, j|
next if (x.empty?)
l = near(x, l1)
et = yt = zt = 0
l.each \
{
|x1|
e = (x1[ky] - x[ky]).abs
yt += x1[ky]
et += e
zt += x1['z']
a = {'er' => e, 'j' => j, 'z' => x1['z']}
x1['nn'] << a
}
x['y'] = yt / l.size
x['er1'] = et / l.size
x['z'] = zt / l.size
e1 += x['er1']
}
et = e1 / l2.size
return et
end
def sum(l)
return l.inject(0) { |t, x| t + x }
end
def avg(l)
return sum(l).to_f / l.size
end
def opt(l2, l1)
et = predict(l2, l1)
l1.each { |x| x['er2'] = x['nn'].empty? ? 0 : avg(x['nn'].map { |x1| x1['er'] }) }
j = (0...l1.size).max_by { |x| l1[x].fetch('er2', 0) }
x = l1[j]
a = {'et' => et, 'er2max' => x['er2'], 'j' => j}
return a
end
def outd(f, l)
f.puts('$dat << eof')
k = l[0].keys
f.puts(k.join("\t"))
l.each { |x| f.puts(x.values.join("\t")) }
f.puts('eof')
return k
end
def hide(a, x)
return (a.member?(x) && a[x].nil?)
end
def outa(f, l, a = {}, t = '')
k = outd(f, l)
f.puts("set colors classic; set title '#{t}'; ")
# f.puts("set key top right opaque; ")
# f.puts("set ytics nomirror; set y2tics;")
f.puts("plot \\")
ct = ''
k, ct = [k - ['t'], "(column('t')):"] if (k.member?('t') && !hide(a, 't'))
k.each \
{
|x|
next if (hide(a, x))
opt = a.fetch(x, '')
opt = ' with line lw 2 ' + opt if (!opt.include?('with'))
f.puts("'$dat' using #{ct}(column('#{x}')) #{opt} title '#{x}',\\")
}
f.puts
# f.puts("reset; pause -1;")
end
def outafn(l, a = {}, fn = nil, t = '')
fn = 'gnuplot.cmd' if (fn.nil?)
outa(f = File.open(fn, 'w'), l, a, t)
f.close
$stderr.puts([fn, l.size, t].inspect)
end
def cg(l2)
cg = l2.index { |x| x < l2[0] }
return cg
end
def seqg(n)
n1 = n
l = [n1]
while (n != 1 && n >= n1)
n = f2(n)
l << n
end
return l
end
def subglides(l, c)
l3 = []
l.each \
{
|x|
ns = x['ns']
l2 = seqg(ns.to_i(2))
cm = (0...l2.size).max_by { |x| l2[x] }
(0...cm).each \
{
|i|
cg = cg(l2[i..-1])
# next if (cg < 20)
ns = l2[i].to_s(2)
hg = cg.to_f / ns.length
next if (hg < 0.1)
l3 << {'ns' => ns, 'i' => i, 'cg' => cg, $k => hg}
}
}
l3.sort_by! { |x| x[$k] }
$stderr.puts(l3.size)
l4 = sample2(l3, c)
return l4
end
def keys(l, ks)
return l.map \
{
|x|
Hash[[ks, x.values_at(*ks)].transpose]
}
end
def fit(l, l1)
l4 = dataset(l)
predict(l4, l1)
outafn(keys(l4, [$k, 'y', 'z']), {'z' => 'axes x1y2'}, 'gnuplot2.cmd')
outafn(keys(l4, ['d', 'e', 'mx0', 'mx1', 'mx01', 'a0', 'a1', 'a01']), {}, 'gnuplot3.cmd')
ks = ['d', 'e', 'da', 'ea', 'dlo', 'dhi', 'elo', 'ehi', 'mp1', 'mp2', 'mx0', 'mx1', 'mx01', 'a0', 'a1', 'a01', 'a1m']
l1.sort_by! { |x| x[$k] }
outafn(keys(l1, ks), {}, 'gnuplot4.cmd')
end
def review()
f = File.open('outline.txt')
l1 = f.readlines.map { |x| Kernel.eval(x) }
f.close
l = load()
l.each { |x| x['hg'] = x['cg'].to_f / x['ns'].length }
# l3 = fwd(l)
l3 = subglides(l, 1000)
fit(l + [{}] + l3, l1)
exit
end
$k = 'cg'
$k = 'hg'
review() if (File.exists?('outline.txt'))
c1 = 250
l = load()
l = subglides(l, 1000 + c1)
l = dataset(l)
l2b = sample2(l, c1)
l2b.each { |x| l.delete(x) }
l2 = sample2(l, c1)
l2.each { |x| x['y'] = nil }
c2 = c1
(l3 = (0...l.size).select { |x| !l[x].member?('y') }).shuffle[0...c2].each { |x| l[x]['x'] = nil }
f = File.open('out.txt', 'w')
t = 0
emn = emx = et2 = nil
l1 = nil
loop \
{
l1 = l.select { |x| x.member?('x') }
a = opt(l2, l1)
a['et2'] = et2.nil? ? '-' : et2
emx = [emx, a['et']].compact.max
emn = [emn, a['et']].compact.min
a['er'] = a['et'].to_f / emx
a['er2'] = et2.nil? ? '-' : (et2.to_f / emx).round(3)
if (t == 0) then
f.puts(a.keys.join("\t"))
f1 = File.open('gnuplot1.cmd', 'w')
f1.puts("set colors classic; ")
f1.puts("set ytics nomirror; set y2tics; ")
f1.puts("plot \\")
a1 = {'j' => 'pt 5',
'er' => 'with line lw 2 axes x1y2',
'er2' => 'with line lt 7 lw 2 axes x1y2'
}
a.keys.each \
{
|k|
opt = a1.fetch(k, 'with line lw 2')
f1.puts("'out.txt' using (column('#{k}')) #{opt},\\")
}
f1.puts
f1.close
end
f.puts(a.values.join("\t"))
f.flush
break if ((er3 = a['et'].to_f / emn) > 1.10)
l1[a['j']].delete('x')
l4 = (0...l.size).select { |x| l[x].member?('x') }
l5 = l3 - l4
l[i = l5[rand(l5.size)]]['x'] = nil
l4 += [i]
l4.sort!
if ((t + 1) % 5 == 0) then
l6 = (0...l2.size).map \
{
|x|
{'y' => l2[x]['y'],
'e' => l2[x]['er1'],
$k => l2[x][$k],
'cg' => l2[x]['cg'],
'z' => Math.log(l2[x]['z']),
# 'i' => l4[x]
}
}
et2 = predict(l2b, l1)
l2b.size.times { |x| l6[x]['y2'] = l2b[x]['y'] }
outafn(l6, {'cg' => 'axes x1y2', 'y2' => 'lt 7'})
end
t += 1
$stderr.puts({'t' => t,
'er' => a['er'].round(3),
'er2' => a['er2'],
'er3' => er3.round(3)}.inspect)
}
f = File.open('outline.txt', 'w')
l1.each { |x| f.puts(x.inspect) }
f.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment