Advertisement
Guest User

Untitled

a guest
Nov 15th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.26 KB | None | 0 0
  1. package com.nduginets.softwaredesign;
  2.  
  3. import org.apache.commons.math3.distribution.NormalDistribution;
  4.  
  5. import java.util.*;
  6. import java.util.stream.Collectors;
  7. import java.util.stream.IntStream;
  8. import java.util.stream.Stream;
  9.  
  10. public class AAA {
  11.  
  12.  
  13.     public static void main(String[] args) {
  14.         String[] matrixRaw = new String[]{
  15.                 "1000001101",
  16.                 "0100000011",
  17.                 "0010000111",
  18.                 "0001000110",
  19.                 "0000101010",
  20.                 "0000011100",
  21.         };
  22.  
  23.         boolean[] word = new boolean[]{false, true, true, false, false, true};
  24.         boolean[][] matrix = buildMatrix(matrixRaw);
  25.         System.err.printf("Input word: %s\n", Arrays.toString(word));
  26.  
  27.         Encoder encoder = new Encoder(matrix);
  28.         boolean[] codedWord = encoder.codeMessage(word);
  29.         System.err.printf("Coded word: %s\n", Arrays.toString(codedWord));
  30.  
  31.         MessageSender sender = new MessageSender();
  32.         double[] sendedMessage = sender.sendMessage(codedWord);
  33.  
  34.         System.err.printf("Message representing in channel: %s\n", Arrays.toString(sendedMessage));
  35.         Decoder decoder = new Decoder(matrix);
  36.  
  37.         boolean[] hard = decoder.hardDecoder(sendedMessage);
  38.         System.err.printf("Hard decoded message: %s\n", Arrays.toString(hard));
  39.  
  40.         boolean[] soft = decoder.hardDecoder(sendedMessage);
  41.         System.err.printf("Soft decoded message: %s\n", Arrays.toString(soft));
  42.  
  43.         compareAnswers(codedWord, hard);
  44.         compareAnswers(codedWord, soft);
  45.     }
  46.  
  47.     private static boolean[][] buildMatrix(String[] raw) {
  48.         int N = raw[0].length();
  49.         int K = raw.length;
  50.         boolean[][] res = new boolean[K][N];
  51.         for (int k = 0; k < K; k++) {
  52.             for (int n = 0; n < N; n++) {
  53.                 res[k][n] = raw[k].charAt(n) != '0';
  54.             }
  55.         }
  56.         return res;
  57.     }
  58.  
  59.     private static int hammingDistance(boolean[] a, boolean[] b) {
  60.         if (a.length != b.length) {
  61.             throw new IllegalStateException("a length = " + a.length + " b length = " + b.length);
  62.         }
  63.  
  64.         int cnt = 0;
  65.         for (int i = 0; i < a.length; i++) {
  66.             if (a[i] != b[i]) {
  67.                 cnt++;
  68.             }
  69.         }
  70.         return cnt;
  71.     }
  72.  
  73.     private static void compareAnswers(boolean[] trust, boolean[] received) {
  74.         System.err.println("========================");
  75.         int wrong = 0;
  76.         for(int i = 0; i < trust.length; i++) {
  77.             if(trust[i] != received[i]) {
  78.                 wrong++;
  79.             }
  80.         }
  81.         System.err.printf("trust: %s\n", Arrays.toString(trust));
  82.         System.err.printf("recev: %s\n", Arrays.toString(received));
  83.         System.err.printf("different elements: %d\n", wrong);
  84.         System.err.println("========================");
  85.  
  86.     }
  87.  
  88.     private static class MessageSender {
  89.         private final double N0 = 900;
  90.         private final double W = 3400;
  91.         private final double P = 7500000;
  92.         private final double E = P / W;
  93.         private final NormalDistribution GAUSSIAN_DISTRIBUTION = new NormalDistribution(0, Math.sqrt(N0 / 2));
  94.  
  95.  
  96.         double[] sendMessage(boolean[] message) {
  97.             double[] msg = new double[message.length];
  98.             for (int i = 0; i < message.length; i++) {
  99.                 msg[i] = Math.sqrt(E) * (2 * (message[i] ? 1 : 0) - 1) + GAUSSIAN_DISTRIBUTION.sample();
  100.             }
  101.             return msg;
  102.         }
  103.  
  104.  
  105.     }
  106.  
  107.     private static class Encoder {
  108.  
  109.         final boolean[][] gMatrix;
  110.         final int N;
  111.         final int K;
  112.  
  113.         Encoder(boolean[][] gMatrix) {
  114.             this.gMatrix = gMatrix;
  115.             this.K = gMatrix.length;
  116.             this.N = gMatrix[0].length;
  117.         }
  118.  
  119.         boolean[] codeMessage(boolean[] word) {
  120.             if (word.length != K) {
  121.                 throw new IllegalStateException("word size must be equal K");
  122.             }
  123.             boolean[] coded = new boolean[N];
  124.             for (int n = 0; n < N; n++) {
  125.                 boolean sum = false;
  126.                 for (int k = 0; k < K; k++) {
  127.                     sum = sum ^ (gMatrix[k][n] & word[k]);
  128.                 }
  129.                 coded[n] = sum;
  130.             }
  131.             return coded;
  132.         }
  133.     }
  134.  
  135.     private static class Decoder extends Encoder {
  136.         boolean[][] codedWords;
  137.  
  138.         Decoder(boolean[][] gMatrix) {
  139.             super(gMatrix);
  140.             generateCodedWords();
  141.         }
  142.  
  143.         private void generateCodedWords() {
  144.             boolean[][] codedWords = new boolean[(1 << K)][];
  145.             for (int i = 0; i < (1 << K); i++) {
  146.                 boolean[] word = new boolean[K];
  147.                 for (int k = 0; k < K; k++) {
  148.                     word[k] = (i & (1 << k)) > 0;
  149.                 }
  150.                 codedWords[i] = codeMessage(word);
  151.             }
  152.             this.codedWords = codedWords;
  153.         }
  154.  
  155.  
  156.         boolean[] hardDecoder(double[] word) {
  157.             boolean[] message = new boolean[word.length];
  158.             for (int i = 0; i < word.length; i++) {
  159.                 message[i] = word[i] > 0;
  160.             }
  161.  
  162.             List<Integer> dist = Stream.of(codedWords)
  163.                     .map(cw -> hammingDistance(cw, message))
  164.                     .collect(Collectors.toList());
  165.             int maxIndex = IntStream.range(0, codedWords.length)
  166.                     .boxed()
  167.                     .min(Comparator.comparingInt(dist::get))
  168.                     .get();
  169.  
  170.             return codedWords[maxIndex];
  171.         }
  172.  
  173.         boolean[] softDecoder(double[] word) {
  174.  
  175.             List<Double> distances = Stream.of(codedWords)
  176.                     .map(x -> {
  177.                         double res = 0;
  178.                         for (int i = 0; i < x.length; i++) {
  179.                             res += (2 * (x[i] ? 1 : 0) - 1) * word[i];
  180.                         }
  181.                         return res;
  182.                     })
  183.                     .collect(Collectors.toList());
  184.  
  185.             int maxIndex = IntStream.range(0, codedWords.length)
  186.                     .boxed()
  187.                     .min(Comparator.comparingDouble(distances::get))
  188.                     .get();
  189.  
  190.             return codedWords[maxIndex];
  191.         }
  192.     }
  193.  
  194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement