Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.nduginets.softwaredesign;
- import org.apache.commons.math3.distribution.NormalDistribution;
- import java.util.*;
- import java.util.stream.Collectors;
- import java.util.stream.IntStream;
- import java.util.stream.Stream;
- public class AAA {
- public static void main(String[] args) {
- String[] matrixRaw = new String[]{
- "1000001101",
- "0100000011",
- "0010000111",
- "0001000110",
- "0000101010",
- "0000011100",
- };
- boolean[] word = new boolean[]{false, true, true, false, false, true};
- boolean[][] matrix = buildMatrix(matrixRaw);
- System.err.printf("Input word: %s\n", Arrays.toString(word));
- Encoder encoder = new Encoder(matrix);
- boolean[] codedWord = encoder.codeMessage(word);
- System.err.printf("Coded word: %s\n", Arrays.toString(codedWord));
- MessageSender sender = new MessageSender();
- double[] sendedMessage = sender.sendMessage(codedWord);
- System.err.printf("Message representing in channel: %s\n", Arrays.toString(sendedMessage));
- Decoder decoder = new Decoder(matrix);
- boolean[] hard = decoder.hardDecoder(sendedMessage);
- System.err.printf("Hard decoded message: %s\n", Arrays.toString(hard));
- boolean[] soft = decoder.hardDecoder(sendedMessage);
- System.err.printf("Soft decoded message: %s\n", Arrays.toString(soft));
- compareAnswers(codedWord, hard);
- compareAnswers(codedWord, soft);
- }
- private static boolean[][] buildMatrix(String[] raw) {
- int N = raw[0].length();
- int K = raw.length;
- boolean[][] res = new boolean[K][N];
- for (int k = 0; k < K; k++) {
- for (int n = 0; n < N; n++) {
- res[k][n] = raw[k].charAt(n) != '0';
- }
- }
- return res;
- }
- private static int hammingDistance(boolean[] a, boolean[] b) {
- if (a.length != b.length) {
- throw new IllegalStateException("a length = " + a.length + " b length = " + b.length);
- }
- int cnt = 0;
- for (int i = 0; i < a.length; i++) {
- if (a[i] != b[i]) {
- cnt++;
- }
- }
- return cnt;
- }
- private static void compareAnswers(boolean[] trust, boolean[] received) {
- System.err.println("========================");
- int wrong = 0;
- for(int i = 0; i < trust.length; i++) {
- if(trust[i] != received[i]) {
- wrong++;
- }
- }
- System.err.printf("trust: %s\n", Arrays.toString(trust));
- System.err.printf("recev: %s\n", Arrays.toString(received));
- System.err.printf("different elements: %d\n", wrong);
- System.err.println("========================");
- }
- private static class MessageSender {
- private final double N0 = 900;
- private final double W = 3400;
- private final double P = 7500000;
- private final double E = P / W;
- private final NormalDistribution GAUSSIAN_DISTRIBUTION = new NormalDistribution(0, Math.sqrt(N0 / 2));
- double[] sendMessage(boolean[] message) {
- double[] msg = new double[message.length];
- for (int i = 0; i < message.length; i++) {
- msg[i] = Math.sqrt(E) * (2 * (message[i] ? 1 : 0) - 1) + GAUSSIAN_DISTRIBUTION.sample();
- }
- return msg;
- }
- }
- private static class Encoder {
- final boolean[][] gMatrix;
- final int N;
- final int K;
- Encoder(boolean[][] gMatrix) {
- this.gMatrix = gMatrix;
- this.K = gMatrix.length;
- this.N = gMatrix[0].length;
- }
- boolean[] codeMessage(boolean[] word) {
- if (word.length != K) {
- throw new IllegalStateException("word size must be equal K");
- }
- boolean[] coded = new boolean[N];
- for (int n = 0; n < N; n++) {
- boolean sum = false;
- for (int k = 0; k < K; k++) {
- sum = sum ^ (gMatrix[k][n] & word[k]);
- }
- coded[n] = sum;
- }
- return coded;
- }
- }
- private static class Decoder extends Encoder {
- boolean[][] codedWords;
- Decoder(boolean[][] gMatrix) {
- super(gMatrix);
- generateCodedWords();
- }
- private void generateCodedWords() {
- boolean[][] codedWords = new boolean[(1 << K)][];
- for (int i = 0; i < (1 << K); i++) {
- boolean[] word = new boolean[K];
- for (int k = 0; k < K; k++) {
- word[k] = (i & (1 << k)) > 0;
- }
- codedWords[i] = codeMessage(word);
- }
- this.codedWords = codedWords;
- }
- boolean[] hardDecoder(double[] word) {
- boolean[] message = new boolean[word.length];
- for (int i = 0; i < word.length; i++) {
- message[i] = word[i] > 0;
- }
- List<Integer> dist = Stream.of(codedWords)
- .map(cw -> hammingDistance(cw, message))
- .collect(Collectors.toList());
- int maxIndex = IntStream.range(0, codedWords.length)
- .boxed()
- .min(Comparator.comparingInt(dist::get))
- .get();
- return codedWords[maxIndex];
- }
- boolean[] softDecoder(double[] word) {
- List<Double> distances = Stream.of(codedWords)
- .map(x -> {
- double res = 0;
- for (int i = 0; i < x.length; i++) {
- res += (2 * (x[i] ? 1 : 0) - 1) * word[i];
- }
- return res;
- })
- .collect(Collectors.toList());
- int maxIndex = IntStream.range(0, codedWords.length)
- .boxed()
- .min(Comparator.comparingDouble(distances::get))
- .get();
- return codedWords[maxIndex];
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement