Created
May 29, 2020 08:09
-
-
Save kereis/d21785214d5dead93c5408a6cdad4de0 to your computer and use it in GitHub Desktop.
Simulates communication between receiver and sender using CDMA (Code Division Multiple Access)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
/** | |
* <h1>CDMA</h1> | |
* <p>Simulates a spread spectrum communication</p> | |
* <p> | |
* Each {@link Receiver} listens to one chip sequence ({@link Stations}) and can be accept by the {@link Sender}. | |
* A {@link Sender} can send multiple chip sequences at once, added together to a matrix. | |
* Afterwards, each listening {@link Receiver} receives the matrix, | |
* decodes them by computing normalized inner products and checks if the result equals either | |
* <ul> | |
* <li>Bit "1"</li> | |
* <li>Bit "0"</li> | |
* <li>No transmission/silent</li> | |
* </ul> | |
* </p> | |
*/ | |
public class CDMA { | |
/** | |
* Represents chip sequences | |
*/ | |
public enum Stations { | |
// Bit time divided into m intervals called "chips" | |
// Bit time = Time to send one bit | |
// m would equals length of each array. (Array#length()) | |
A(-1, -1, -1, 1, 1, -1, 1, 1), | |
B(-1, -1, 1, -1, 1, 1, 1, -1), | |
C(-1, 1, -1, 1, 1, 1, -1, -1), | |
D(-1, 1, -1, -1, -1, -1, 1, -1); | |
private final int[] sequence; | |
Stations(int... sequence) { | |
this.sequence = sequence; | |
} | |
public int[] getSequence() { | |
return sequence; | |
} | |
} | |
public static class Sender { | |
private final List<Receiver> receivers = new ArrayList<>(); | |
public void accept(Receiver... receivers) { | |
this.receivers.addAll(Arrays.asList(receivers)); | |
} | |
public void send(int[]... sequences) { | |
// 1. Sequence S = a + b ... -> add stations | |
int[] s = { 0, 0, 0, 0, 0, 0, 0, 0 }; | |
for (int[] sequence : sequences) { | |
s = addMatrices(s, sequence); | |
} | |
// 2. Send to receiver | |
for (Receiver receiver : receivers) { | |
receiver.receive(s); | |
} | |
} | |
} | |
public static class Receiver { | |
private final int[] sequenceToReceive; | |
private final String name; | |
public Receiver(String name, int[] sequenceToReceive) { | |
this.sequenceToReceive = sequenceToReceive; | |
this.name = name; | |
} | |
/** | |
* @param sequence that this receiver will consume | |
*/ | |
public void receive(int[] sequence) { | |
// 1. Receive a sequence | |
log("Received sequence:"); | |
printArray(sequence); | |
// 2. Decode with decode(); | |
int result = decode(sequence); | |
// 3. Evaluate result | |
switch (result) { | |
case -1: log("Received sequence matches \"0\""); break; | |
case 0: log("Received sequence does not contain sequence to receive."); break; | |
case 1: log("Received sequence matches \"1\""); break; | |
} | |
} | |
/** | |
* Decodes a sequence by computing the normalized inner product of | |
* - the chip sequence the receiver listens to | |
* - and the received chip sequence | |
* @param s sequence to be decoded | |
* @return 0 = silent transmission, not matching listener sequence | |
* 1 = received sequence equals "1" | |
* -1 = received sequence equals "0" | |
*/ | |
private int decode(int[] s) { | |
int m = sequenceToReceive.length; | |
double innerProduct = 0.0; | |
for (int i = 0; i < sequenceToReceive.length; i++) { | |
innerProduct = innerProduct + (s[i] * sequenceToReceive[i]); | |
} | |
innerProduct = innerProduct * (1.0/m); | |
return (int) Math.round(innerProduct); | |
} | |
private void log(String text) { | |
System.out.println("<" + name + "> " + text); | |
} | |
} | |
public static int[] addMatrices(int[] a, int[] b) { | |
int[] result = new int[b.length]; | |
for (int i = 0; i < b.length; i++) { | |
result[i] = a[i] + b[i]; | |
} | |
return result; | |
} | |
/** | |
* This is used if the sender wants to send "0". | |
* @param sequence to be negated | |
* @return negated sequence as array | |
*/ | |
public static int[] negativeSequence(int... sequence) { | |
int[] result = new int[sequence.length]; | |
for (int i = 0; i < result.length; i++) { | |
result[i] = sequence[i] * (-1); | |
} | |
return result; | |
} | |
public static void printArray(int... ints) { | |
System.out.print("[\t"); | |
for (int i : ints) { | |
System.out.print(i + "\t"); | |
} | |
System.out.println(']'); | |
} | |
public static void main(String[] args) { | |
Sender sender = new Sender(); | |
Receiver receiverA = new Receiver("A Receiver", Stations.A.getSequence()); | |
Receiver receiverB = new Receiver ("B Receiver", Stations.B.getSequence()); | |
Receiver receiverC = new Receiver("C Receiver", Stations.C.getSequence()); | |
sender.accept(receiverA, receiverB, receiverC); | |
System.out.println("--------------------"); | |
System.out.println(" Sending following sequences: B + C"); | |
sender.send( | |
Stations.C.getSequence(), | |
Stations.B.getSequence() | |
); | |
System.out.println(); | |
System.out.println("--------------------"); | |
System.out.println(" Sending following sequences: -A + C + D"); | |
sender.send( | |
negativeSequence(Stations.A.getSequence()), | |
Stations.C.getSequence(), | |
Stations.D.getSequence() | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment