Skip to content

Instantly share code, notes, and snippets.

@kereis
Created May 29, 2020 08:09
Show Gist options
  • Save kereis/d21785214d5dead93c5408a6cdad4de0 to your computer and use it in GitHub Desktop.
Save kereis/d21785214d5dead93c5408a6cdad4de0 to your computer and use it in GitHub Desktop.
Simulates communication between receiver and sender using CDMA (Code Division Multiple Access)
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