def test_q_notations(): from_notation = Format.from_notation format_ = Q(15) assert format_ == Q(1, 15) assert format_.msb == 0 assert format_.lsb == -15 assert format_.signed assert format_ == from_notation('Q1.15') format_ = Q(1, 7) assert format_.msb == 0 assert format_.lsb == -7 assert format_.signed assert format_ == from_notation('Q1.7') format_ = Q(3, -1) assert format_.msb == 2 assert format_.lsb == 1 assert format_.signed assert format_ == from_notation('Q3.-1') format_ = uQ(15) assert format_ == uQ(1, 15) assert format_.msb == 1 assert format_.lsb == -15 assert not format_.signed assert format_ == from_notation('uQ1.15') format_ = uQ(4, -2) assert format_.msb == 4 assert format_.lsb == 2 assert not format_.signed assert format_ == from_notation('uQ4.-2')
def test_represent(): alu = MultiFormatArithmeticLogicUnit( wordlength=8, rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=False, allows_underflow=False ) assert alu.rinfo(signed=True).eps == 0.0078125 assert alu.rinfo(signed=True).min == -128 assert alu.rinfo(signed=True).max == 127 assert alu.rinfo(signed=False).eps == 0.00390625 assert alu.rinfo(signed=False).min == 0 assert alu.rinfo(signed=False).max == 256 r = alu.represent(0.5) assert r.mantissa == 64 assert r.format_ == Q(7) r = alu.represent(0) assert r.mantissa == 0 assert r.format_ == Q(7) r = alu.represent(1.25) assert r.mantissa == 80 assert r.format_ == Q(2, 6) r = alu.represent(1.25, format_=Q(3, 4)) assert r.mantissa == 20 assert r.format_ == Q(3, 4) r = alu.represent(1.25, format_=uQ(3, 5)) assert r.mantissa == 40 assert r.format_ == uQ(3, 5) r = alu.represent(12.5) assert r.mantissa == 100 assert r.format_ == Q(5, 3) r = alu.represent(12.5, format_=Q(6, 2)) assert r.mantissa == 50 assert r.format_ == Q(6, 2) r = alu.represent(12.5, format_=uQ(4, 4)) assert r.mantissa == 200 assert r.format_ == uQ(4, 4) r = alu.represent(15.6) assert r.mantissa == 125 assert r.format_ == Q(5, 3) r = alu.represent(interval(-1, 1)) assert r.mantissa == interval(-64, 64) assert r.format_ == Q(2, 6)
def test_multiply(): alu = MultiFormatArithmeticLogicUnit( wordlength=8, rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=False, allows_underflow=False ) x = alu.represent(1, format_=Q(4, 4)) y = alu.represent(2, format_=Q(4, 4)) z = alu.multiply(x, y) assert z.mantissa == 64 assert z.format_ == Q(3, 5)
def test_error_bounded_addition(): a = error_bounded(1., interval(-0.1, 0.3)) b = error_bounded(1., interval(-0.3, 0.2)) c = a + b assert c.number == 2. assert math.isclose(c.error_bounds.lower_bound, -0.4) assert math.isclose(c.error_bounds.upper_bound, 0.5) d = a + 2 assert d.number == 3. assert d.error_bounds == a.error_bounds e = 1 + b assert e.number == 2. assert e.error_bounds == b.error_bounds f = error_bounded(interval(-1, 1), interval(-0.1, 0.2)) g = a + f assert g.number == interval(0, 2) assert g.error_bounds == interval(-0.2, 0.5) with FixedFormatArithmeticLogicUnit( format_=Q(7), rounding_method=nearest_integer ): h = (a + (-0.5)) + fixed(0.2) assert h.number == fixed(0.7) assert a.error_bounds in h.error_bounds
def test_represent(): alu = FixedFormatArithmeticLogicUnit(format_=Q(7), rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=False, allows_underflow=False) assert alu.rinfo().eps == 0.0078125 assert alu.rinfo().min == -1 assert alu.rinfo().max == 0.9921875 r = alu.represent(0) assert r.mantissa == 0 assert r.format_ == alu.format_ r = alu.represent(0.25) assert r.mantissa == 32 assert r.format_ == alu.format_ r = alu.represent(-0.25) assert r.mantissa == -32 assert r.format_ == alu.format_ r = alu.represent(0.3) assert r.mantissa == 38 assert r.format_ == alu.format_ r = alu.represent(-0.3) assert r.mantissa == -38 assert r.format_ == alu.format_ r = alu.represent(interval(-0.75, 0.75)) assert r.mantissa == interval(-96, 96) assert r.format_ == alu.format_
def test_symbolic_expression(): with FixedFormatArithmeticLogicUnit( format_=Q(7), allows_overflow=False, rounding_method=nearest_integer) as alu: x, y, z, w = sympy.symbols('x y z w') expr = ((x + 0.5 * y) * z) - w subs = {x: fixed(0.25), y: fixed(0.1), z: 0.25, w: 0.5} result = expr.subs(subs) assert math.isclose(result, -0.425, abs_tol=2**alu.format_.lsb)
def test_realization_error_bounds(realization_type): model = signal.dlti([1], [1, -0.5]) # y[n] = x[n - 1] - 0.5 y[n - 1] block = realization_type.from_model(model) with FixedFormatArithmeticLogicUnit( format_=Q(7), allows_overflow=False, rounding_method=nearest_integer, ): assert block.computation_error_bounds(interval(-0.25, 0.25)) in \ 10 * nearest_integer.error_bounds(-7) # reasonable tolerance
def test_nonassociative_expression(): with MultiFormatArithmeticLogicUnit( wordlength=8, allows_overflow=False, allows_underflow=True, rounding_method=nearest_integer, ) as alu: x, y, z, w = sympy.symbols('x y z w') expr = x + y + z + w subs = { x: fixed(2**-5, format_=Q(2, 5)), y: fixed(2**-3, format_=Q(3, 4)), z: fixed(2**-1, format_=Q(4, 3)), w: fixed(2, format_=Q(5, 2)) } result0 = nonassociative(variant=0)(expr).subs(subs) result1 = nonassociative(variant=1)(expr).subs(subs) assert math.isclose(result0, result1, abs_tol=2**result0.format_.lsb) assert result0 != result1
def test_represent_errors(): alu = MultiFormatArithmeticLogicUnit( wordlength=8, rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=False, allows_underflow=False ) with pytest.raises(ValueError): alu.represent(-1, format_=uQ(8)) with pytest.raises(UnderflowError): alu.represent(1e-3, format_=Q(7)) with pytest.raises(OverflowError): alu.represent(10, format_=Q(7)) with pytest.raises(ValueError): alu.represent(0, format_=Q(15))
def test_represent_errors(): alu = FixedFormatArithmeticLogicUnit(format_=Q(7), rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=False, allows_underflow=False) with pytest.raises(UnderflowError): alu.represent(1e-3) with pytest.raises(OverflowError): alu.represent(10)
def test_multiply(): alu = FixedFormatArithmeticLogicUnit(format_=Q(7), rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=False, allows_underflow=False) x = alu.represent(0.5) y = alu.represent(0.5) z = alu.multiply(x, y) assert z.mantissa == 32 assert z.format_ == alu.format_
def test_add(): alu = FixedFormatArithmeticLogicUnit(format_=Q(4, 4), rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=True, allows_underflow=False) x = alu.represent(1) y = alu.represent(2) z = alu.add(x, y) assert z.mantissa == 48 assert z.format_ == alu.format_ x = alu.represent(4) z = alu.add(x, x) assert z.mantissa == -128 assert z.format_ == alu.format_ y = alu.represent(-2) z = alu.add(x, y) assert z.mantissa == 32 assert z.format_ == alu.format_ x = alu.represent(interval(-1, 1)) y = alu.represent(interval(3, 5)) z = alu.add(x, y) assert z.mantissa == interval(32, 96) assert z.format_ == alu.format_ x = alu.represent(interval(-1, 3)) y = alu.represent(interval(3, 5)) z = alu.add(x, y) # NOTE(hidmic): this ALU handles overflow # in interval arithmetic by assuming the # value may be anywhere (how many cycles # does e.g. [32, -32] imply?) # TODO(hidmic): revisit result assert z.mantissa == interval(-128, 127) assert z.format_ == alu.format_
def test_add(): alu = MultiFormatArithmeticLogicUnit( wordlength=8, rounding_method=nearest_integer, overflow_behavior=wraparound, allows_overflow=False, allows_underflow=False ) x = alu.represent(1, format_=Q(4, 4)) y = alu.represent(2, format_=Q(4, 4)) z = alu.add(x, y) assert z.mantissa == 48 assert z.format_ == Q(4, 4) x = alu.represent(1, format_=Q(2, 6)) y = alu.represent(2, format_=Q(3, 5)) z = alu.add(x, y) assert z.mantissa == 96 assert z.format_ == Q(3, 5) x = alu.represent(1, format_=Q(2, 6)) y = alu.represent(-2, format_=Q(3, 5)) z = alu.add(x, y) assert z.mantissa == -32 assert z.format_ == Q(3, 5) x = alu.represent(interval(-1, 1), format_=Q(2, 6)) y = alu.represent(interval(3, 5), format_=Q(4, 4)) z = alu.add(x, y) assert z.mantissa == interval(32, 96) assert z.format_ == Q(4, 4) x = alu.represent(interval(-1, 1), format_=Q(2, 6)) y = alu.represent(interval(3, 5), format_=Q(4, 4)) z = alu.add(x, y) assert z.mantissa == interval(32, 96) assert z.format_ == Q(4, 4)
def test_mixed_symbols(): with FixedFormatArithmeticLogicUnit(format_=Q(7), allows_overflow=False): a = sympy.sympify(fixed(0.5)) b = sympy.sympify(error_bounded(0.25)) assert (a * b).number == fixed(0.125)
pretty(biquad_cascade).draw('biquad.png') func = signal_processing_function(biquad_cascade) output_noise = func(input_noise).T[0].astype(float) _, output_noise_power_density = psd(output_noise) biquad_cascade_response = \ 10 * np.log10(output_noise_power_density / input_noise_power_density + 1/inf) plt.figure() plt.plot(freq, expected_response, label='Model') if show_biquad_cascade: plt.plot(freq, biquad_cascade_response, label='Biquad cascade') pass plt.plot(freq, optimized_implementation_a_response, label='Optimized realization A') plt.plot(freq, optimized_implementation_b_response, label='Optimized realization B') plt.xlabel('Frecuency $f$ [Hz]') plt.ylabel('Response $|H(f)|$ [dBr]') plt.legend() plt.savefig('response.png') plt.show() if __name__ == '__main__': with FixedFormatArithmeticLogicUnit(format_=Q(15), allows_overflow=True, overflow_behavior=wraparound): main()
def test_literal_conversion(): with FixedFormatArithmeticLogicUnit( format_=Q(7), rounding_method=nearest_integer) as alu: assert Fixed(0.25) == sympy.sympify(fixed(0.25))