mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-10 00:41:06 +00:00
123 lines
3.1 KiB
Python
Executable File
123 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2022 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
def fast_exp2(x, p):
|
|
|
|
p = p.astype(np.float32)
|
|
x = x.astype(np.float32)
|
|
|
|
y = (((((p[0]*x) + p[1])*x + p[2])*x + p[3])*x + p[4])*x + 1
|
|
|
|
return np.power(y.astype(np.float32), 16)
|
|
|
|
def approx_exp2():
|
|
|
|
x = np.arange(-8, 8, step=1e-3)
|
|
|
|
p = np.polyfit(x, ((2 ** (x/16)) - 1) / x, 4)
|
|
y = [ fast_exp2(x[i], p) for i in range(len(x)) ]
|
|
e = np.abs(y - 2**x) / (2 ** x)
|
|
|
|
print('{{ {:14.8e}, {:14.8e}, {:14.8e}, {:14.8e}, {:14.8e} }}'
|
|
.format(p[0], p[1], p[2], p[3], p[4]))
|
|
print('Max relative error: ', np.max(e))
|
|
print('Max RMS error: ', np.sqrt(np.mean(e ** 2)))
|
|
|
|
if False:
|
|
fig, (ax1, ax2) = plt.subplots(2)
|
|
|
|
ax1.plot(x, 2**x, label='Reference')
|
|
ax1.plot(x, y, label='Approximation')
|
|
ax1.legend()
|
|
|
|
ax2.plot(x, e, label='Relative Error')
|
|
ax2.legend()
|
|
|
|
plt.show()
|
|
|
|
|
|
def fast_log2(x, p):
|
|
|
|
p = p.astype(np.float32)
|
|
x = x.astype(np.float32)
|
|
|
|
(x, e) = np.frexp(x)
|
|
|
|
y = ((((p[0]*x) + p[1])*x + p[2])*x + p[3])*x + p[4]
|
|
|
|
return (e ) + y.astype(np.float32)
|
|
|
|
def approx_log2():
|
|
|
|
x = np.logspace(-1, 0, base=2, num=100)
|
|
p = np.polyfit(x, np.log2(x), 4)
|
|
|
|
x = np.logspace(-2, 5, num=10000)
|
|
y = [ fast_log2(x[i], p) for i in range(len(x)) ]
|
|
e = np.abs(y - np.log2(x))
|
|
|
|
print('{{ {:14.8e}, {:14.8e}, {:14.8e}, {:14.8e}, {:14.8e} }}'
|
|
.format(p[0], p[1], p[2], p[3], p[4]))
|
|
print('Max absolute error: ', np.max(e))
|
|
print('Max RMS error: ', np.sqrt(np.mean(e ** 2)))
|
|
|
|
if False:
|
|
fig, (ax1, ax2) = plt.subplots(2)
|
|
|
|
ax1.plot(x, np.log2(x), label='Reference')
|
|
ax1.plot(x, y, label='Approximation')
|
|
ax1.legend()
|
|
|
|
ax2.plot(x, e, label = 'Absolute error')
|
|
ax2.legend()
|
|
|
|
plt.show()
|
|
|
|
|
|
def table_db_q16():
|
|
|
|
k = 10 * np.log10(2);
|
|
|
|
for i in range(32):
|
|
a = k * np.log2(np.ldexp(32 + i , -5)) - (i // 16) * (k/2);
|
|
b = k * np.log2(np.ldexp(32 + i+1, -5)) - (i // 16) * (k/2);
|
|
|
|
an = np.ldexp(a, 15) + 0.5
|
|
bn = np.ldexp(b - a, 15) + 0.5
|
|
print('{{ {:5d}, {:4d} }},'
|
|
.format(int(np.ldexp(a, 15) + 0.5),
|
|
int(np.ldexp(b - a, 15) + 0.5)),
|
|
end = ' ' if i % 4 < 3 else '\n')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
print('\n--- Approximation of 2^n ---')
|
|
approx_exp2()
|
|
|
|
print('\n--- Approximation of log2(n) ---')
|
|
approx_log2()
|
|
|
|
print('\n--- Table of fixed Q16 dB ---')
|
|
table_db_q16()
|
|
|
|
print('')
|