def test_invert(): x = Fxp(None, True, 8, 4) xu = Fxp(None, False, 8, 4) x('0b 0010 1100') y = ~x assert y.bin() == '11010011' x('0b0000 0000') assert (~x).bin() == '11111111' xu('0b0000 0000') assert (~xu).bin() == '11111111' x('0b 1111 1111') assert (~x).bin() == '00000000' xu('0b 1111 1111') assert (~xu).bin() == '00000000' x('0b 1000 0000') assert (~x).bin() == '01111111' xu('0b 1000 0000') assert (~xu).bin() == '01111111' x = Fxp(None, True, 32, 0) xu = Fxp(None, False, 32, 0) val_str = '10100000111101011100001100110101' inv_str = '01011111000010100011110011001010' x('0b' + val_str) assert (~x).bin() == inv_str xu('0b' + val_str) assert (~xu).bin() == inv_str
def test_numpy_ufunc(): vx = [-1., 0., 1.] vy = [1., 2., 4.] vc = [1j * 0.5, 1.5 + 1j * 2.0, -0.5 + 1j * 0] nx = np.asarray(vx) ny = np.asarray(vy) nc = np.asarray(vc) fx = Fxp(vx, True, 16 * 8, 8 * 8) fy = Fxp(vy, True, 12 * 8, 4 * 8) fc = Fxp(vc, True, 12 * 8, 4 * 8) c = 2. ufunc_one_param_list = [ np.positive, np.negative, np.conj, np.exp, np.abs, np.sin, ] for ufunc in ufunc_one_param_list: assert (ufunc(nx) == ufunc(fx)()).all() assert (ufunc(ny) == ufunc(fy)()).all() assert (ufunc(nc) == ufunc(fc)()).all() ufunc_one_positive_param_list = [ np.log, np.log10, np.sqrt, ] for ufunc in ufunc_one_positive_param_list: assert np.allclose(ufunc(ny), ufunc(fy)(), rtol=fy.precision) ufunc_two_params_list = [ np.add, np.subtract, np.multiply, np.divide, ] for ufunc in ufunc_two_params_list: assert (ufunc(nx, c) == ufunc(fx, c)()).all() assert (ufunc(ny, c) == ufunc(fy, c)()).all() assert (ufunc(nx, ny) == ufunc(fx, fy)()).all() assert (ufunc(nx, ny) == ufunc(nx, fy)()).all() assert (ufunc(nx, ny) == ufunc(fx, ny)()).all() ufunc_two_array_params_list = [ np.matmul, ] for ufunc in ufunc_two_array_params_list: assert (ufunc(nx, ny) == ufunc(fx, fy)()).all() assert (ufunc(nx, ny) == ufunc(nx, fy)()).all() assert (ufunc(nx, ny) == ufunc(fx, ny)()).all()
def test_operations_with_combinations(): v = [-256, -64, -16, -4.75, -3.75, -3.25, -1, -0.75, -0.125, 0.0, 0.125, 0.75, 1, 1.5, 3.75, 4.0, 8.0, 32, 128] for i in range(len(v)): for j in range(len(v)): vx, vy = v[i], v[j] x = Fxp(vx) y = Fxp(vy) assert (vx + vy) == (x + y)() assert (vy + vx) == (y + x)() assert (vx - vy) == (x - y)() assert -(vy - vx) == -(y - x)() assert (vx * vy) == (x * y)() assert (vy * vx) == (y * x)() v = [-256, -64, -16, -4.75, -4.25, -1, -0.75, -0.125, 0.125, 0.75, 1, 1.5, 2.75, 4.0, 8.0, 32, 128] d = [-256, -64, -16, -1, -0.5, -0.125, 0.125, 0.5, 1, 2, 4.0, 8.0, 32, 128] for i in range(len(v)): for j in range(len(d)): vx, vy = v[i], d[j] x = Fxp(vx) y = Fxp(vy) assert (vx / vy) == (x / y)() assert (vx // vy) == (x // y)() assert (vx % vy) == (x % y)()
def test_rounding(): # trunc x = Fxp(None, True, 8, 2, rounding='trunc') vi = [0.00, 1.00, 1.24, 1.25, 1.26, 1.49, 1.50] vo = [0.00, 1.00, 1.00, 1.25, 1.25, 1.25, 1.50] for i, o in zip(vi, vo): assert x(i) == o assert x(-i) == -o # ceil x = Fxp(None, True, 8, 2, rounding='ceil') vi = [ 0.00, 1.00, 1.24, 1.25, 1.26, 1.49, 1.50, -1.00, -1.24, -1.25, -1.26, -1.49, -1.50 ] vo = [ 0.00, 1.00, 1.25, 1.25, 1.50, 1.50, 1.50, -1.00, -1.00, -1.25, -1.25, -1.25, -1.50 ] for i, o in zip(vi, vo): assert x(i) == o # floor x = Fxp(None, True, 8, 2, rounding='floor') vi = [ 0.00, 1.00, 1.24, 1.25, 1.26, 1.49, 1.50, -1.00, -1.24, -1.25, -1.26, -1.49, -1.50 ] vo = [ 0.00, 1.00, 1.00, 1.25, 1.25, 1.25, 1.50, -1.00, -1.25, -1.25, -1.50, -1.50, -1.50 ] for i, o in zip(vi, vo): assert x(i) == o # fix x = Fxp(None, True, 8, 2, rounding='fix') vi = [ 0.00, 1.00, 1.24, 1.25, 1.26, 1.49, 1.50, -1.00, -1.24, -1.25, -1.26, -1.49, -1.50 ] vo = [ 0.00, 1.00, 1.00, 1.25, 1.25, 1.25, 1.50, -1.00, -1.00, -1.25, -1.25, -1.25, -1.50 ] for i, o in zip(vi, vo): assert x(i) == o # around x = Fxp(None, True, 8, 2, rounding='around') vi = [ 0.00, 1.00, 1.24, 1.25, 1.26, 1.49, 1.50, -1.00, -1.24, -1.25, -1.26, -1.49, -1.50 ] vo = [ 0.00, 1.00, 1.25, 1.25, 1.25, 1.50, 1.50, -1.00, -1.25, -1.25, -1.25, -1.50, -1.50 ] for i, o in zip(vi, vo): assert x(i) == o
def test_reduce_func(): vx = [-1., 0., 1.] vy = [1., 2., 3.] vc = [1j*0.5, 1.5 + 1j*2.0, -0.5 + 1j*0] nx = np.asarray(vx) ny = np.asarray(vy) nc = np.asarray(vc) fx = Fxp(vx, True, 16, 8) fy = Fxp(vy, True, 12, 4) fc = Fxp(vc, True, 12, 4) c = 2.5 ufunc_one_param_list = [ np.sum, np.mean, ] for ufunc in ufunc_one_param_list: assert (ufunc(nx) == ufunc(fx)()).all() assert (ufunc(ny) == ufunc(fy)()).all() assert (ufunc(nc) == ufunc(fc)()).all() ufunc_two_array_params_list = [ np.inner, np.dot ] for ufunc in ufunc_two_array_params_list: assert (ufunc(nx, ny) == ufunc(fx, fy)()).all() assert (ufunc(nx, ny) == ufunc(nx, fy)()).all() assert (ufunc(nx, ny) == ufunc(fx, ny)()).all()
def test_like(): ref = Fxp(0.0, True, 16, 4) x = Fxp(4.5, like=ref) assert x is not ref assert x() == 4.5 assert x.n_word == ref.n_word assert x.n_frac == ref.n_frac assert x.signed == ref.signed
def test_init_by_raw(): x = Fxp(16, True, 8, 4, raw=True) assert x() == 1.0 x = Fxp(16, None, None, 4, raw=True) assert x() == 1.0 x = Fxp('0b1111', n_frac=1, raw=True) assert x() == -0.5
def test_arrays(): x = Fxp(None, True, 8, 4) y = Fxp(None, True, 8, 4) x(['0b00110101', '0b10101100']) y('0b11110000') z = x & y assert z.bin()[0] == '00110000' assert z.bin()[1] == '10100000'
def test_math_operators(): x = Fxp(1.0, True, 256, 248) y = Fxp(-0.1, True, 128, 96) z = x + y assert z() == 0.9 assert (x - y)() == 1.1 assert (x * y)() == -0.1 assert (x / y)() == -10.0
def test_bugs_0_3_2(): # fail in Win32 because numpy astype(int) behavior x = Fxp(1.25, False, 3, 1) assert (x >> 1)() == 0.5 # wrap error x = Fxp(4.5, False, 3, 1, overflow='wrap') assert x() == 0.5 assert x(4.0) == 0.0 assert x(5.0) == 1.0 assert (x([3.5, 4.0, 4.5, 5.0])() == np.array([3.5, 0.0, 0.5, 1.0])).all()
def test_bugs_0_2_2(): x = Fxp('0b1100') assert x() == -4 assert x.n_word == 4 assert x.signed == True assert x.n_frac == 0 x = Fxp('0b11.00') assert x() == -1.0 assert x.n_word == 4 assert x.signed == True assert x.n_frac == 2
def test_issue_26_v0_4_0(): sig = np.array(['0xff864d8f', '0xff86b76d', '0xff880f87']) fxp_sig = Fxp(sig) assert fxp_sig[0] == -7975537 assert fxp_sig[1] == -7948435 assert fxp_sig[2] == -7860345 fxp_sig = Fxp(sig, signed=False) assert fxp_sig[0] == int('0xff864d8f', 16) assert fxp_sig[1] == int('0xff86b76d', 16) assert fxp_sig[2] == int('0xff880f87', 16)
def test_issue_21_v0_3_8(): a = [1, 2, 3] b = [0, 1, 0] assert (np.inner(a, b) == 2) na = np.array([1, 2, 3]) nb = np.array([0, 1, 0]) assert (np.inner(na, nb) == np.inner(a, b)).all() fa = Fxp([1, 2, 3]) fb = Fxp([0, 1, 0]) z = np.inner(fa, fb) assert (np.inner(fa, fb)() == np.inner(a, b)).all()
def test_strvals(): x = Fxp('0b0110') assert x() == 6 x = Fxp('0b110', True, 4, 0) assert x() == -2 x = Fxp('0b110', False, 4, 0) assert x() == 6 x = Fxp('0b0110.01', True, 8) assert x() == 6.25 x = Fxp(0.0, True, 8, 4) x('0x8c') assert x() == -7.25
def test_issue_14_v0_3_7(): # d = Fxp('0b000.00000000000000000001011101010110101011101010101010101010101010101010101010101001010101010101010101001010101001010101010101010', # True, n_word=128, n_frac=125, rounding='around') # assert d.bin(frac_dot=True) == '000.00000000000000000001011101010110101011101010101010101010101010101010101010101001010101010101010101001010101001010101010101010' d = Fxp( '0b00000000000000000000001011101010110101011101010101010101010101010101010101010101001010101010101010101001010101001010101010101010', True, n_word=128, n_frac=125, rounding='around', raw=True) assert d.bin( ) == '00000000000000000000001011101010110101011101010101010101010101010101010101010101001010101010101010101001010101001010101010101010'
def test_wrap(): x = Fxp(3.75, False, 4, 2, overflow='wrap') assert x() == 3.75 assert x.status['overflow'] == False assert x.status['underflow'] == False x(4.0) assert x() == 0.0 assert x.status['overflow'] == True assert x.status['underflow'] == False x.reset() x(-0.25) assert x() == 3.75 assert x.status['overflow'] == False assert x.status['underflow'] == True x = Fxp(3.75, True, 5, 2, overflow='wrap') assert x() == 3.75 assert x.status['overflow'] == False assert x.status['underflow'] == False x(4.0) assert x() == -4.0 assert x.status['overflow'] == True assert x.status['underflow'] == False x.reset() x(-4.25) assert x() == 3.75 assert x.status['overflow'] == False assert x.status['underflow'] == True
def test_issue_20_v0_3_8(): x = Fxp(0, signed=True, n_word=4, n_frac=0, overflow='wrap') assert x(-30) == 2 assert x(-8) == -8 assert x(-9) == 7 assert x(7) == 7 assert x(8) == -8
def test_scaling(): x = Fxp(4.5, scale=2.0, bias=-1.5) assert x() == 4.5 assert x.n_word == 3 assert x.n_frac == 0 assert x.upper == 4.5 assert x.lower == -9.5 assert x.precision == 2.0 x = Fxp(1003, False, scale=0.5, bias=1000) assert x() == 1003 assert x.n_word == 3 assert x.n_frac == 0 assert x.upper == 1003.5 assert x.lower == 1000 assert x.precision == 0.5 x = Fxp(10128.5, signed=False, n_word=12, scale=1, bias=10000) assert x() == 10128.5 assert x.n_word == 12 assert x.n_frac == 1 assert x.upper == 12047.5 assert x.lower == 10000.0 assert x.precision == 0.5 assert x.get_status(str) == ''
def test_signed(): # signed x_fxp = Fxp(0.0, True, 8, 7) x_fxp(0.5) assert x_fxp() == 0.5 x_fxp(-0.5) assert x_fxp() == -0.5 # unsigned x_fxp = Fxp(0.0, False, 8, 7) x_fxp(0.5) assert x_fxp() == 0.5 x_fxp(-0.5) assert x_fxp() == 0.0
def test_issue_11_v0_3_6(): try: val = np.float128(1.5) except: val = None if val is not None: x = Fxp(val, True, 256, 64) assert x() == 1.5
def test_scaled(): x = Fxp(10.5, True, 16, 8, scale=2, bias=1) assert x() == 10.5 assert x + 2 == 12.5 assert x - 2.5 == 8.0 assert x * 3 == 31.5 assert x / 2 == 5.25
def test_issue_9_v0_3_6(): M = 24 N = 16 A_fxp = Fxp(np.zeros((M, N)), True, 16, 8) # indexed element returned as Fxp object assert isinstance(A_fxp[0], Fxp) # accept an Fxp object like input value x = Fxp(4, True, 8, 2) A_fxp[0, 0] = x assert A_fxp[0, 0]() == 4 B_fxp = Fxp(x, like=A_fxp) assert B_fxp() == 4 C_fxp = Fxp(x) assert C_fxp() == 4
def test_xor(): x = Fxp(None, True, 8, 4) xu = Fxp(None, False, 8, 4) y = Fxp(None, True, 8, 4) yu = Fxp(None, False, 8, 4) val_str = '00110101' mks_str = '11110000' xor_str = '11000101' x('0b' + val_str) xu('0b' + val_str) y('0b' + mks_str) yu('0b' + mks_str) assert (x ^ y).bin() == xor_str assert (x ^ yu).bin() == xor_str assert (xu ^ y).bin() == xor_str assert (xu ^ yu).bin() == xor_str assert (x ^ utils.str2num('0b' + mks_str)).bin() == xor_str assert (xu ^ utils.str2num('0b' + mks_str)).bin() == xor_str assert (utils.str2num('0b' + mks_str) ^ x).bin() == xor_str assert (utils.str2num('0b' + mks_str) ^ xu).bin() == xor_str val_str = '10101100' mks_str = '11001100' xor_str = '01100000' x('0b' + val_str) xu('0b' + val_str) y('0b' + mks_str) yu('0b' + mks_str) assert (x ^ y).bin() == xor_str assert (x ^ yu).bin() == xor_str assert (xu ^ y).bin() == xor_str assert (xu ^ yu).bin() == xor_str assert (x ^ utils.str2num('0b' + mks_str)).bin() == xor_str assert (xu ^ utils.str2num('0b' + mks_str)).bin() == xor_str assert (utils.str2num('0b' + mks_str) ^ x).bin() == xor_str assert (utils.str2num('0b' + mks_str) ^ xu).bin() == xor_str
def test_or(): x = Fxp(None, True, 8, 4) xu = Fxp(None, False, 8, 4) y = Fxp(None, True, 8, 4) yu = Fxp(None, False, 8, 4) val_str = '00110101' mks_str = '11110000' or_str = '11110101' x('0b' + val_str) xu('0b' + val_str) y('0b' + mks_str) yu('0b' + mks_str) assert (x | y).bin() == or_str assert (x | yu).bin() == or_str assert (xu | y).bin() == or_str assert (xu | yu).bin() == or_str assert (x | utils.str2num('0b' + mks_str)).bin() == or_str assert (xu | utils.str2num('0b' + mks_str)).bin() == or_str assert (utils.str2num('0b' + mks_str) | x).bin() == or_str assert (utils.str2num('0b' + mks_str) | xu).bin() == or_str val_str = '10101100' mks_str = '11001100' or_str = '11101100' x('0b' + val_str) xu('0b' + val_str) y('0b' + mks_str) yu('0b' + mks_str) assert (x | y).bin() == or_str assert (x | yu).bin() == or_str assert (xu | y).bin() == or_str assert (xu | yu).bin() == or_str assert (x | utils.str2num('0b' + mks_str)).bin() == or_str assert (xu | utils.str2num('0b' + mks_str)).bin() == or_str assert (utils.str2num('0b' + mks_str) | x).bin() == or_str assert (utils.str2num('0b' + mks_str) | xu).bin() == or_str
def test_and(): x = Fxp(None, True, 8, 4) xu = Fxp(None, False, 8, 4) y = Fxp(None, True, 8, 4) yu = Fxp(None, False, 8, 4) val_str = '00110101' mks_str = '11110000' and_str = '00110000' x('0b' + val_str) xu('0b' + val_str) y('0b' + mks_str) yu('0b' + mks_str) assert (x & y).bin() == and_str assert (x & yu).bin() == and_str assert (xu & y).bin() == and_str assert (xu & yu).bin() == and_str assert (x & utils.str2num('0b' + mks_str)).bin() == and_str assert (xu & utils.str2num('0b' + mks_str)).bin() == and_str assert (utils.str2num('0b' + mks_str) & x).bin() == and_str assert (utils.str2num('0b' + mks_str) & xu).bin() == and_str val_str = '10101100' mks_str = '11001100' and_str = '10001100' x('0b' + val_str) xu('0b' + val_str) y('0b' + mks_str) yu('0b' + mks_str) assert (x & y).bin() == and_str assert (x & yu).bin() == and_str assert (xu & y).bin() == and_str assert (xu & yu).bin() == and_str assert (x & utils.str2num('0b' + mks_str)).bin() == and_str assert (xu & utils.str2num('0b' + mks_str)).bin() == and_str assert (utils.str2num('0b' + mks_str) & x).bin() == and_str assert (utils.str2num('0b' + mks_str) & xu).bin() == and_str
def test_saturate(): x = Fxp(0.0, True, 8, 2) assert x.upper == 31.75 assert x.lower == -32.00 assert x.status['overflow'] == False assert x.status['underflow'] == False assert x(32.00) == 31.75 assert x.status['overflow'] == True assert x.status['underflow'] == False x.reset() assert x.status['overflow'] == False assert x.status['underflow'] == False assert x(-32.25) == -32.00 assert x.status['overflow'] == False assert x.status['underflow'] == True assert x(32.00) == 31.75 assert x.status['overflow'] == True assert x.status['underflow'] == True
def test_outputs_formats(): values = [[1, 2, 3], [-1, 0, 1]] w = Fxp(values, True, 16, 8) like_ref = Fxp(None, True, 24, 12) out_ref = Fxp(None, True, 24, 8) z = np.add(w, 2, out_like=like_ref) assert isinstance(z, Fxp) assert z.n_frac == like_ref.n_frac assert z.n_int == like_ref.n_int assert (z.get_val() == np.array(values) + 2).all() z = np.add(w, 2, out=out_ref) assert isinstance(z, Fxp) assert z is out_ref assert z.n_frac == out_ref.n_frac assert z.n_int == out_ref.n_int assert (z.get_val() == np.array(values) + 2).all() # np.std(w, out_like=like_ref)
def test_creation(): x = Fxp(1.0, True, 256, 248) y = Fxp(-0.1, True, 128, 96) assert x() == 1.0 assert y() == -0.1 decimal.getcontext().prec = int(np.ceil(math.log10(2**248))) h_decimal = Decimal(1) / Decimal(3) h = Fxp(h_decimal, True, 256, 248) assert h.astype(float) == float(h_decimal) h = Fxp(h_decimal) assert h.astype(float) == float(h_decimal) w_vals = [0.1, 0.2, 0.3, 0.4, 0.5] w = Fxp(w_vals, True, 256, 248) assert (w() == np.array(w_vals)).all()
def test_perf_change_2d_indexed_value(m=24, n=16, repeat=10): A_fxp = Fxp(np.random.uniform(size=[m, n])) x = 1 / repeat exec_time_vals = np.zeros(repeat) for r in range(repeat): start_time = time.time() for i in range(m): for j in range(n): A_fxp[i, j] = A_fxp[i, j] + x exec_time_vals[r] = time.time() - start_time print( '\ntest_perf_change_2d_indexed_value execution time over {} repetitions' .format(repeat)) print('\tmean = {:.3f} ms\n\tstd = {:.3f} ms'.format( np.mean(exec_time_vals) * 1e3, np.std(exec_time_vals) * 1e3))
def test_misc_values(): # huges x = Fxp(2**31 - 1) assert x() == 2**31 - 1 x = Fxp(-2**31) assert x() == -2**31 x = Fxp(2**63 - 1) assert x() == 2**63 - 1 x = Fxp(-2**63) assert x() == -2**63 x = Fxp(2**32 - 1, signed=False) assert x() == 2**32 - 1 x = Fxp(-2**32, signed=False) assert x() == 0 x = Fxp(2**64 - 1, signed=False) assert x() == 2**64 - 1 x = Fxp(-2**63, signed=False) assert x() == 0