Skip to content

Instantly share code, notes, and snippets.

@Strikeskids
Created January 29, 2014 14: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 Strikeskids/8688615 to your computer and use it in GitHub Desktop.
Save Strikeskids/8688615 to your computer and use it in GitHub Desktop.
from sys import argv
from math import pi, log10, floor
res = [10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91]
cap = [res[x] for x in range(len(res)) if x % 2 == 0]
pre = {
'cheb': [[1.231],[1.842],[.597,1.031],[1.582,2.660]],
'bessel': [[1.272],[1.268],[1.432,1.606],[1.084,1.759]]
}
class SkipValue:
def __init__(self, arr, index = 0, mult = 0):
self.index = 0
self.mult = mult
self.arr = arr
def up(self):
self.index += 1
if self.index == len(self.arr):
self.index = 0
self.mult += 1
return self.value()
def down(self):
self.index -= 1
if self.index < 0:
self.index = len(self.arr)-1
self.mult -= 1
return self.value()
def value(self):
return self.arr[self.index] * 10 ** self.mult
def toTuple(self):
return (self.arr[self.index], self.mult, self.value())
def calcGain(k):
if k <= 0: return None
best = (1e100, None, None)
r1 = SkipValue(res, mult = 4)
while r1.value() >= 1e3:
r2 = approx(r1.value() * k, res)
if r2.value() < 1e3 or r2.value() > 1e5:
r1.down()
continue
dist = abs(r2.value() / r1.value() - k)
if dist < best[0]:
best = (dist, r1.toTuple(), r2.toTuple())
r1.down()
return best
def calcRC(value):
r = SkipValue(res, mult = 4)
best = (1e100, None, None)
while r.value() >= 1e3:
c = approx(value / r.value(), cap)
if c.mult < -11 or c.mult > -6:
r.down()
continue
dist = abs(r.value() * c.value() - value)
if dist < best[0]:
best = (dist, r.toTuple(), c.toTuple())
r.down()
return best
def approx(value, arr):
valueLog = log10(value)
base = floor(valueLog)
index = (valueLog - base) * len(arr)
up = SkipValue(arr, index = index, mult = base)
down = SkipValue(arr, index = index, mult = base)
best = abs(up.value() - value)
while abs(up.up() - value) < best:
best = abs(up.value() - value)
up.down()
while abs(down.down() - value) < best:
best = abs(down.value() - value)
down.up()
if abs(up.value() - value) < abs(down.value() - value):
return up
else:
return down
poles = int(argv[1])
fc = int(argv[2])
if argv[3] in pre:
fns = pre[argv[3]][poles-2]
ks = pre[argv[3]][poles-1]
else:
fns = list(map(lambda x: float(x), argv[3:3+poles//2]))
ks = list(map(lambda x: float(x), argv[3+poles//2:4+poles]))
des = 1/(2 * pi * fc)
gains = []
lowpass = []
highpass =[]
for stage in range(poles//2):
print("Stage",stage)
fn = fns[stage]
k = ks[stage]
print("Fn",fn,"Gain",k)
gains.append(calcGain(k-1))
lowpass.append(calcRC(des / fn))
highpass.append(calcRC(des * fn))
print('G',gains)
print('L',lowpass)
print('H',highpass)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment