In the book about GPS-SDRs is a description of the Goldsequence. This is a pseudorandom-series with interesting correlation properties. It is implemented using two shiftregisters. The following javacode does the trick:
/** * A class to represent Gold Sequence Generators for GPS */ /** * @author Kees * */ public class GoldSequence { /** * note: in the literature the shiftregisters * are numbered from left to right 1 to 10 * we number them 0 to 9, * so tap n in literature, here is tap n-1 */ // the two ten-bit shiftregisters private int[] shreg1, shreg2; private int tap1, tap2; private int count4, temp4; private int[][] magnum = { {2,6}, {3,7}, {4,8}, {5,9}, {1,9}, {2,10}, {1,8}, {2,9}, {3,10},{2,3}, {3,4}, {5,6}, {6,7}, {7,8}, {8,9}, {9,10},{1,4}, {2,5}, {3,6}, {4,7}, {5,8}, {6,9}, {1,3}, {4,6}, {5,7}, {6,8}, {7,9}, {8,10}, {1,6}, {2,7}, {3,8}, {4,9}, {5,10},{4,10}, {1,7}, {2,8}, {4,10} }; /** construct a GoldSequence */ public GoldSequence(int a, int b) { tap1 = a - 1; tap2 = b - 1; shreg1 = new int[10]; shreg2 = new int[10]; count4 = 0; temp4 = 0; for (int i=0; i < 10; i++) { shreg1[i] = 1; shreg2[i] = 1; } } public GoldSequence(int n) { // n = 1..37 this(0, 0); tap1 = magnum[n - 1][0] - 1; tap2 = magnum[n - 1][1] - 1; } public int next() { int shback1, shback2, temp1; int result = 0; // save rightmost bits // calculate the shiftback-values shback1 = shreg1[9] ^ shreg1[2]; shback2 = shreg2[9] ^ shreg2[8] ^ shreg2[7] ^ shreg2[5] ^ shreg2[2] ^ shreg2[1]; temp1 = shreg1[9]; result = shreg2[tap1] ^ shreg2[tap2] ^ temp1; for (int i = 9; i > 0; i--) { shreg1[i] = shreg1[i - 1]; shreg2[i] = shreg2[i - 1]; } shreg1[0] = shback1; shreg2[0] = shback2; return result; } public void reset() { count4 = 0; temp4 = 0; for (int i=0; i < 10; i++) { shreg1[i] = 1; shreg2[i] = 1; } } public int nextan() { // return analogue result +1 or -1 int result = 0; result = 1 - 2 * this.next(); return result; } public int nextan4() { int result = temp4; if (count4 == 0) { temp4 = this.nextan(); } count4++; if (count4 == 4) { count4 = 0; } return result; } public String getRegs() { String result1 = ""; String result2 = ""; for (int i=0; i<10; i++) { result1 = result1 + shreg1[i]; result2 = result2 + shreg2[i]; } return result1 + " " + result2; } } |
The little program to test the sequence {2,6}:
public void fillArray9() { GoldSequence gold26 = new GoldSequence(2,6); System.out.print("First 10 chips: "); for (int i = 0; i < 10; i++) { System.out.print(gold26.next()); } System.out.println(); } |
The output:
First 10 chips: 1100100000
This is a strong indication that the program might be correct.
now check that the sequence repeats
public void fillArray10() { // show the sequence is repeating after 1023 chips GoldSequence gold26 = new GoldSequence(2,6); System.out.print("First 20 chips: "); for (int i = 0; i < 20; i++) { System.out.print(gold26.next()); } System.out.println(); for (int i = 20; i < 1023; i++) { gold26.next(); } System.out.print("After 1023 chips:"); for (int i = 0; i < 20; i++) { System.out.print(gold26.next()); } } |
And output:
First 20 chips: 11001000001110010100 After 1023 chips:11001000001110010100
The output indicates proper working of the class GoldSequence
correlation experiment
public void fillArray11() { // correlation experiments // construct a test-input with 4000 samples of Gold26 // find the match-point int inplen = 4000; int[] testinput = new int[inplen]; int[] bins = new int[inplen]; System.out.println("experiment 11. Correlation"); GoldSequence gold26 = new GoldSequence(2,6); // throw away first 35 chips for (int i = 0; i < 35; i++) { gold26.nextan(); } for (int i = 0; i < testinput.length; i++) { testinput[i] = gold26.nextan(); } gold26.reset(); for (int i = 0; i < inplen; i++) { gold26.reset(); int acc = 0; for (int j = 0; j < 1023; j++) { if ((i + j) < inplen) { acc = acc + testinput[i + j] * gold26.nextan(); } } bins[i] = acc; } for (int i = 0; i < inplen; i++) { System.out.println(i + " " + bins[i]); } } |
And output (cut away part to save paper/ink/screen/whatever):
experiment 11. Correlation 0 -65 1 -1 2 -1 3 -65 4 -1 5 -1 6 -65 7 -1 8 -1 9 -65 10 -1 11 -1 12 -1 13 -65 14 63 15 -1 16 -1 ... 986 -1 987 -1 988 1023 989 -1 990 -1 991 -1 992 -1 ... 2002 63 2003 -1 2004 -1 2005 -1 2006 -1 2007 -1 2008 -1 2009 -1 2010 -1 2011 1023 2012 -1 2013 -1 2014 -1 2015 -1 2016 -1 2017 -1 2018 -1 2019 -1 2020 63 ... 2021 -1 2022 -1 2023 -1 2024 -1 2025 -1 2026 63 2027 -1 2028 -1 2029 -65 2030 -1 2031 63 2032 -1 3029 -11 3030 -4 3031 5 3032 0 3033 -3 3034 966 3035 -3 3036 2 3037 9
Because the first 35 values are thrown away, the first correlation peak is at 1023 - 35 = 988. Next at n*1023 = 2011 and 3034.
Theorie predicts smaller peaks of -65 etc. At the end the values are lower because of truncation.
To test the internal shiftregisters:
public void fillArray12() { System.out.println("Experiment 12. Print internal regs"); GoldSequence gold26 = new GoldSequence(2,6); for (int i=0; i<1040; i++) { System.out.println(i + " " + gold26.getRegs()); gold26.next(); } } |
And output (cut away part to save paper/ink/screen/whatever):
0 1111111111 1111111111 1 0111111111 0111111111 2 0011111111 0011111111 3 0001111111 1001111111 4 1000111111 0100111111 5 1100011111 1010011111 6 1110001111 1101001111 7 0111000111 0110100111 8 0011100011 1011010011 9 0001110001 0101101001 10 1000111000 0010110100 11 0100011100 1001011010 12 0010001110 0100101101 13 1001000111 1010010110 14 1100100011 0101001011 15 1110010001 1010100101 16 0111001000 1101010010 17 1011100100 1110101001 18 1101110010 1111010100 19 0110111001 0111101010 20 0011011100 1011110101 21 1001101110 0101111010 22 0100110111 1010111101 23 1010011011 0101011110 24 0101001101 0010101111 25 1010100110 0001010111 26 1101010011 0000101011 27 1110101001 0000010101 28 0111010100 1000001010 29 1011101010 1100000101 30 1101110101 1110000010 31 1110111010 1111000001 32 1111011101 1111100000 33 0111101110 0111110000 34 1011110111 1011111000 1012 0000001110 1100000010 1013 0000000111 0110000001 1014 1000000011 1011000000 1015 1100000001 1101100000 1016 1110000000 1110110000 1017 1111000000 1111011000 1018 1111100000 1111101100 1019 1111110000 1111110110 1020 1111111000 1111111011 1021 1111111100 1111111101 1022 1111111110 1111111110 1023 1111111111 1111111111 1024 0111111111 0111111111 1025 0011111111 0011111111 1026 0001111111 1001111111 1027 1000111111 0100111111 1028 1100011111 1010011111 1029 1110001111 1101001111 1030 0111000111 0110100111 1031 0011100011 1011010011 1032 0001110001 0101101001 1033 1000111000 0010110100 1034 0100011100 1001011010 1035 0010001110 0100101101 1036 1001000111 1010010110 1037 1100100011 0101001011 1038 1110010001 1010100101 1039 0111001000 1101010010
At 1023 everything is the same as the initial position.