test_max_len_seq.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. from __future__ import division, print_function, absolute_import
  2. import numpy as np
  3. from numpy.testing import assert_allclose, assert_array_equal
  4. from pytest import raises as assert_raises
  5. from numpy.fft import fft, ifft
  6. from scipy.signal import max_len_seq
  7. class TestMLS(object):
  8. def test_mls_inputs(self):
  9. # can't all be zero state
  10. assert_raises(ValueError, max_len_seq,
  11. 10, state=np.zeros(10))
  12. # wrong size state
  13. assert_raises(ValueError, max_len_seq, 10,
  14. state=np.ones(3))
  15. # wrong length
  16. assert_raises(ValueError, max_len_seq, 10, length=-1)
  17. assert_array_equal(max_len_seq(10, length=0)[0], [])
  18. # unknown taps
  19. assert_raises(ValueError, max_len_seq, 64)
  20. # bad taps
  21. assert_raises(ValueError, max_len_seq, 10, taps=[-1, 1])
  22. def test_mls_output(self):
  23. # define some alternate working taps
  24. alt_taps = {2: [1], 3: [2], 4: [3], 5: [4, 3, 2], 6: [5, 4, 1], 7: [4],
  25. 8: [7, 5, 3]}
  26. # assume the other bit levels work, too slow to test higher orders...
  27. for nbits in range(2, 8):
  28. for state in [None, np.round(np.random.rand(nbits))]:
  29. for taps in [None, alt_taps[nbits]]:
  30. if state is not None and np.all(state == 0):
  31. state[0] = 1 # they can't all be zero
  32. orig_m = max_len_seq(nbits, state=state,
  33. taps=taps)[0]
  34. m = 2. * orig_m - 1. # convert to +/- 1 representation
  35. # First, make sure we got all 1's or -1
  36. err_msg = "mls had non binary terms"
  37. assert_array_equal(np.abs(m), np.ones_like(m),
  38. err_msg=err_msg)
  39. # Test via circular cross-correlation, which is just mult.
  40. # in the frequency domain with one signal conjugated
  41. tester = np.real(ifft(fft(m) * np.conj(fft(m))))
  42. out_len = 2**nbits - 1
  43. # impulse amplitude == test_len
  44. err_msg = "mls impulse has incorrect value"
  45. assert_allclose(tester[0], out_len, err_msg=err_msg)
  46. # steady-state is -1
  47. err_msg = "mls steady-state has incorrect value"
  48. assert_allclose(tester[1:], -1 * np.ones(out_len - 1),
  49. err_msg=err_msg)
  50. # let's do the split thing using a couple options
  51. for n in (1, 2**(nbits - 1)):
  52. m1, s1 = max_len_seq(nbits, state=state, taps=taps,
  53. length=n)
  54. m2, s2 = max_len_seq(nbits, state=s1, taps=taps,
  55. length=1)
  56. m3, s3 = max_len_seq(nbits, state=s2, taps=taps,
  57. length=out_len - n - 1)
  58. new_m = np.concatenate((m1, m2, m3))
  59. assert_array_equal(orig_m, new_m)