丸めによるわずかな値の違いが気にならない場合は、それを非常にうまく圧縮できます。
from math import pi, sin
interval=2*pi/1024
sinval=lambda i:int(round(sin(i*interval)*36))+50
これは、実際に必要なことを行うためのコードです。それは動作します
vals = sorted((sinval(i), i) for i in range(1024))
テストデータとして。最初の列にインデックスがある場合は、ここでループ内のval
andの順序を切り替える必要があります。index
for
ranges, oldval, oldidx = [[0, 0]], 0, 0
for val, index in vals:
if not (val == oldval and index == oldidx + 1):
ranges[-1].append(oldidx)
ranges.append([val, index])
oldval, oldidx = val, index
ranges[-1].append(oldidx)
ranges.pop(0)
ifs = ('if((index >= {1}) and (index <= {2})) return {0};\n'.format(val, start, end)
for val, start, end in ranges)
print ''.join(ifs)
編集:おっと、行がありませんでした。修理済み。また、乗数は実際には 35 ではなく 36 でした。頭の中で (14, 86) を (15, 85) に丸めたに違いありません。
編集 2: テーブルの 4 分の 1 のみを保存する方法を示します。
from math import pi, sin
full = 1024
half = 512
quarter = 256
mag = 72
offset = 50
interval = 2 * pi / full
def sinval(i):
return int(round(sin(i * interval) * (mag // 2))) + offset
vals = [sinval(i) for i in range(quarter)]
def sintable(i):
if i >= half + quarter:
return 2 * offset - vals[full - i - 1]
elif i >= half:
return 2 * offset - vals[i - half]
elif i >= quarter:
return vals[half - i - 1]
else:
return vals[i]
for i in range(full):
assert -1 <= sinval(i) - sintable(i) <= 1
テーブルからオフセットを差し引く場合は、-vals[...]
代わりに最初の 2 つを作成します。
また、一番下の比較はあいまいです。これは 72 個の off-by-one エラーが発生するためです。これは、値が整数に丸められているためです。これらはすべて 2 つの値の中間にあるため、精度の低下はほとんどありません。