Skip to content

Commit 1d2fe18

Browse files
authored
Merge pull request #91. (Fix #70)
Fix CAZAC sequence
2 parents 65bfc19 + ac51ec6 commit 1d2fe18

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

commpy/sequences.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""
1616
__all__ = ['pnsequence', 'zcsequence']
1717

18+
import numpy as np
1819
from numpy import empty, exp, pi, arange, int8, fromiter, sum
1920

2021
def pnsequence(pn_order, pn_seed, pn_mask, seq_length):
@@ -72,23 +73,40 @@ def pnsequence(pn_order, pn_seed, pn_mask, seq_length):
7273

7374
return pnseq
7475

75-
def zcsequence(u, seq_length):
76+
def zcsequence(u, seq_length, q=0):
7677
"""
7778
Generate a Zadoff-Chu (ZC) sequence.
7879
7980
Parameters
8081
----------
8182
u : int
82-
Root index of the the ZC sequence.
83+
Root index of the the ZC sequence: u>0.
8384
8485
seq_length : int
85-
Length of the sequence to be generated. Usually a prime number.
86+
Length of the sequence to be generated. Usually a prime number:
87+
u<seq_length, greatest-common-denominator(u,seq_length)=1.
88+
89+
q : int
90+
Cyclic shift of the sequence (default 0).
8691
8792
Returns
8893
-------
8994
zcseq : 1D ndarray of complex floats
9095
ZC sequence generated.
9196
"""
92-
zcseq = exp((-1j * pi * u * arange(seq_length) * (arange(seq_length)+1)) / seq_length)
97+
98+
for el in [u,seq_length,q]:
99+
if not float(el).is_integer():
100+
raise ValueError('{} is not an integer'.format(el))
101+
if u<=0:
102+
raise ValueError('u is not stricly positive')
103+
if u>=seq_length:
104+
raise ValueError('u is not stricly smaller than seq_length')
105+
if np.gcd(u,seq_length)!=1:
106+
raise ValueError('the greatest common denominator of u and seq_length is not 1')
107+
108+
cf = seq_length%2
109+
n = np.arange(seq_length)
110+
zcseq = np.exp( -1j * np.pi * u * n * (n+cf+2.*q) / seq_length)
93111

94112
return zcseq

commpy/tests/test_sequences.py

+32-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
# Authors: CommPy contributors
22
# License: BSD 3-Clause
33

4+
import numpy as np
45
from numpy import array
5-
from numpy.testing import run_module_suite, assert_raises, assert_equal
6-
7-
from commpy.sequences import pnsequence
6+
from numpy.testing import run_module_suite, assert_raises, assert_equal, assert_almost_equal
87

8+
from commpy.sequences import pnsequence, zcsequence
99

1010
def test_pnsequence():
1111
# Test the raises of errors
1212
with assert_raises(ValueError):
1313
pnsequence(4, '001', '1101', 2**4 - 1)
14+
with assert_raises(ValueError):
1415
pnsequence(4, '0011', '110', 2 ** 4 - 1)
1516

1617
# Test output with
@@ -19,6 +20,34 @@ def test_pnsequence():
1920
assert_equal(pnsequence(4, (0, 0, 1, 1), array((1, 1, 0, 1)), 7), array((1, 1, 0, 0, 1, 0, 1), int),
2021
err_msg='Pseudo-noise sequence is not the one expected.')
2122

23+
def test_zcsequence():
24+
# Test the raises of errors
25+
with assert_raises(ValueError):
26+
zcsequence(u=-1, seq_length=20, q=0)
27+
with assert_raises(ValueError):
28+
zcsequence(u=20, seq_length=0, q=0)
29+
with assert_raises(ValueError):
30+
zcsequence(u=3, seq_length=18, q=0)
31+
with assert_raises(ValueError):
32+
zcsequence(u=3.1, seq_length=11, q=0)
33+
with assert_raises(ValueError):
34+
zcsequence(u=3, seq_length=11.1, q=0)
35+
with assert_raises(ValueError):
36+
zcsequence(u=3, seq_length=11, q=0.1)
37+
38+
# Test output with
39+
assert_almost_equal(zcsequence(u=1, seq_length=2, q=0), array([1.000000e+00+0.j, 6.123234e-17-1.j]),
40+
err_msg='CAZAC sequence is not the expected one.')
41+
42+
# Test if output cross-correlation is valid
43+
seqCAZAC = zcsequence(u=3, seq_length=20, q=0)
44+
x = np.fft.fft(seqCAZAC) / np.sqrt(seqCAZAC.size)
45+
h = (np.fft.ifft(np.conj(x) * x)*np.sqrt(seqCAZAC.size)).T
46+
corr = np.absolute(h)**2/h.size
47+
assert_almost_equal(corr[0], 1.,
48+
err_msg='CAZAC sequence auto-correlation is not valid, first term is not 1')
49+
assert_almost_equal(corr[1:], np.zeros(corr.size-1),
50+
err_msg='CAZAC sequence auto-correlation is not valid, all terms except first are not 0')
2251

2352
if __name__ == "__main__":
2453
run_module_suite()

0 commit comments

Comments
 (0)