1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tools/dividers.py Fri Sep 22 21:55:54 2023 +0200
1.3 @@ -0,0 +1,97 @@
1.4 +#!/usr/bin/env python2
1.5 +
1.6 +from math import ceil, floor
1.7 +import sys
1.8 +
1.9 +def method2(f, s):
1.10 + r = f / s
1.11 + scale = getscale(r)
1.12 + return scale * r, scale
1.13 +
1.14 +def is_integer(x):
1.15 + target = round(x) * 1000
1.16 + #print x, target - 100, floor(x * 1000), target + 100
1.17 + return target - 100 < floor(x * 1000) < target + 100
1.18 +
1.19 +def getscale(x):
1.20 + scale = getscale_part(x)
1.21 + if is_integer(scale):
1.22 + return scale
1.23 + return scale * getscale(scale)
1.24 +
1.25 +def getscale_part(x):
1.26 + part = x - int(x)
1.27 + if not part:
1.28 + return 1
1.29 + elif part > 0.5:
1.30 + return 1 / (1 - part)
1.31 + else:
1.32 + return 1 / part
1.33 +
1.34 +def reduce(m, n, m_limit, n_limit):
1.35 + while m > m_limit and n > n_limit and m > 1 and n > 1:
1.36 + m /= 2
1.37 + n /= 2
1.38 + return m, n
1.39 +
1.40 +def show(s, m, n, f_label="f"):
1.41 + print "m =", m
1.42 + print "n =", n
1.43 + print "%s' =" % f_label, s * m / n
1.44 + print "%s' ~=" % f_label, s * round(m) / round(n)
1.45 +
1.46 +if len(sys.argv) < 4:
1.47 + f, s = map(float, sys.argv[1:3])
1.48 + m, n = method2(f, s)
1.49 + m, n = reduce(m, n, 0x200, 0x100000)
1.50 + show(s, m, n)
1.51 +
1.52 +else:
1.53 + f, s, i_min, i_max = map(float, sys.argv[1:5])
1.54 +
1.55 + # Constraints:
1.56 + #
1.57 + # i_min < s * m' / di < i_max
1.58 + # i_min / s < m' / di < i_max / s
1.59 + #
1.60 + # f = s * m' / (di * do)
1.61 + # f = (s * m' / di) / do
1.62 + # f * do = s * m' / di
1.63 + #
1.64 + # i_min < f * do < i_max
1.65 + # i_min / f < do < i_max / f
1.66 + #
1.67 + # f = s * m / n
1.68 + #
1.69 + # s * m' / (di * do) = s * m / n
1.70 + # m' / (di * do) = m / n
1.71 + # m' = (m / n) * (di * do)
1.72 + # m' / di = (m / n) * do
1.73 +
1.74 + do_min = ceil(i_min / f)
1.75 + do_max = floor(i_max / f)
1.76 +
1.77 + do = do_min
1.78 +
1.79 + print do_min, "<= do <=", do_max
1.80 +
1.81 + while do <= do_max:
1.82 + do0 = int(do ** 0.5)
1.83 + do1 = int(do / do0)
1.84 + if do0 * do1 == int(do):
1.85 + i = do * f
1.86 + m, n = method2(i, s)
1.87 + m, n = reduce(m, n, 0x3f, 0x3f)
1.88 + if m <= 0x3f and n <= 0x3f:
1.89 + show(i, m, n, "i")
1.90 + print "do =", do
1.91 + print "do0 =", do0
1.92 + print "do1 =", do1
1.93 + print "f' =", s * m / (n * do)
1.94 + print "f' ~=", s * round(m) / (round(n) * round(do))
1.95 + break
1.96 + else:
1.97 + print "Ignored: m =", m, "n =", n, "do0 =", do0, "do1 =", do1
1.98 + do += 1
1.99 +
1.100 +# vim: tabstop=4 expandtab shiftwidth=4