├── README.md ├── docker ├── build_jupyter.sh ├── jupyter-dockerfile ├── jupyter_notebook_config.py ├── run_jupyter_cpu.sh └── run_jupyter_gpu.sh └── notebooks ├── .ipynb_checkpoints └── On Deep Learning-Based Channel Decoding-checkpoint.ipynb ├── On Deep Learning-Based Channel Decoding.ipynb └── map ├── polar ├── results_polar_map_16_1.txt ├── results_polar_map_16_2.txt ├── results_polar_map_16_3.txt ├── results_polar_map_16_4.txt ├── results_polar_map_16_5.txt ├── results_polar_map_16_6.txt ├── results_polar_map_16_7.txt └── results_polar_map_16_8.txt └── random ├── results_random_map_16_1.txt ├── results_random_map_16_2.txt ├── results_random_map_16_3.txt ├── results_random_map_16_4.txt ├── results_random_map_16_5.txt ├── results_random_map_16_6.txt ├── results_random_map_16_7.txt └── results_random_map_16_8.txt /README.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | Download from GitHub 3 | 4 | git clone git@github.com:gruberto/DL-ChannelDecoding.git 5 | cd DL-ChannelDecoding/docker 6 | 7 | Build docker container which contains jupyter 8 | 9 | ./build_jupyter.sh 10 | 11 | # Start Jupyter 12 | Start jupyter with theano on a CPU 13 | 14 | ./run_jupyter_cpu.sh theano 15 | 16 | Start jupyter with theano on a GPU 17 | 18 | ./run_jupyter_gpu.sh theano 19 | 20 | Access Jupyter Notebooks in a browser on 21 | 22 | http://[ip-adress]:8888 23 | -------------------------------------------------------------------------------- /docker/build_jupyter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -f jupyter-dockerfile \ 3 | -t gruber/nn-decoding-jupyter . 4 | -------------------------------------------------------------------------------- /docker/jupyter-dockerfile: -------------------------------------------------------------------------------- 1 | FROM nvidia/cuda:cudnn 2 | 3 | MAINTAINER Tobias Gruber 4 | 5 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ 6 | build-essential \ 7 | wget \ 8 | git \ 9 | curl \ 10 | libfreetype6-dev \ 11 | libpng12-dev \ 12 | libzmq3-dev \ 13 | libhdf5-dev \ 14 | pkg-config \ 15 | python3-numpy \ 16 | python3-pip \ 17 | python3-scipy \ 18 | python3-dev \ 19 | python3-h5py \ 20 | python3-yaml \ 21 | python3-matplotlib \ 22 | && \ 23 | apt-get clean && \ 24 | rm -rf /var/lib/apt/lists/* 25 | 26 | 27 | ############ 28 | ## THEANO ## 29 | ############ 30 | 31 | RUN pip3 install --upgrade --no-deps git+git://github.com/Theano/Theano.git 32 | 33 | 34 | ################ 35 | ## TENSORFLOW ## 36 | ################ 37 | 38 | RUN pip3 install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.8.0rc0-cp34-cp34m-linux_x86_64.whl 39 | 40 | 41 | ########### 42 | ## KERAS ## 43 | ########### 44 | 45 | RUN pip3 install scipy keras 46 | 47 | 48 | ############# 49 | ## JUPYTER ## 50 | ############# 51 | 52 | # install Jupyter 53 | RUN pip3 install jupyter 54 | 55 | # Jupyter setup 56 | COPY jupyter_notebook_config.py /root/.jupyter/ 57 | 58 | 59 | ######### 60 | ## END ## 61 | ######### 62 | 63 | EXPOSE 8888 64 | WORKDIR /root/data 65 | CMD jupyter notebook --no-browser 66 | -------------------------------------------------------------------------------- /docker/jupyter_notebook_config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | c.NotebookApp.ip = '*' 17 | c.NotebookApp.port = 8888 18 | c.NotebookApp.open_browser = False 19 | c.MultiKernelManager.default_kernel_name = 'python2' 20 | c.NotebookApp.token = '' 21 | c.NotebookApp.password = '' 22 | -------------------------------------------------------------------------------- /docker/run_jupyter_cpu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "theano" ]; then 4 | keras="KERAS_BACKEND=theano" 5 | else 6 | if [ "$1" == "tensorflow" ]; then 7 | keras="KERAS_BACKEND=tensorflow" 8 | else 9 | echo "Use default theano backend for keras" 10 | keras="KERAS_BACKEND=theano" 11 | fi 12 | fi 13 | 14 | path=$PWD 15 | folder=${PWD##*/} 16 | length=`expr ${#path} - ${#folder}` 17 | mountpath=${path:0:$length} 18 | 19 | theano="THEANO_FLAGS=device=cpu" 20 | 21 | docker run -it --rm --privileged \ 22 | -p 8888:8888 \ 23 | --env="$keras" \ 24 | --env="$theano" \ 25 | --volume=$mountpath:/root/data \ 26 | gruber/nn-decoding-jupyter 27 | 28 | -------------------------------------------------------------------------------- /docker/run_jupyter_gpu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "theano" ]; then 4 | keras="KERAS_BACKEND=theano" 5 | else 6 | if [ "$1" == "tensorflow" ]; then 7 | keras="KERAS_BACKEND=tensorflow" 8 | else 9 | echo "Use default theano backend for keras" 10 | keras="KERAS_BACKEND=theano" 11 | fi 12 | fi 13 | 14 | path=$PWD 15 | folder=${PWD##*/} 16 | length=`expr ${#path} - ${#folder}` 17 | mountpath=${path:0:$length} 18 | 19 | theano="THEANO_FLAGS=lib.cnmem=0,device=gpu0" 20 | 21 | nvidia-docker run -it --rm --privileged \ 22 | -p 8888:8888 \ 23 | --env="$keras" \ 24 | --env="$theano" \ 25 | --volume=$mountpath:/root/data \ 26 | gruber/nn-decoding-jupyter 27 | 28 | -------------------------------------------------------------------------------- /notebooks/.ipynb_checkpoints/On Deep Learning-Based Channel Decoding-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# On Deep Learning-Based Channel Decoding\n", 8 | "\n", 9 | "Please cite derivative works\n", 10 | "\n", 11 | " @article{nn-decoding,\n", 12 | " title={On Deep Learning-Based Channel Decoding},\n", 13 | " author={Gruber, Tobias and Cammerer, Sebastian and Hoydis, Jakob and ten Brink, Stephan}\n", 14 | " year={2016}\n", 15 | " }\n", 16 | "\n", 17 | "To run this example you will need Keras installed with either the Theano or TensorFlow backend working. A Dockerfile is provided to employ this setup quickly. For GPU support nvidia-docker is required.\n", 18 | "\n", 19 | "Have fun!" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "metadata": { 26 | "collapsed": false 27 | }, 28 | "outputs": [ 29 | { 30 | "name": "stderr", 31 | "output_type": "stream", 32 | "text": [ 33 | "Using Theano backend.\n", 34 | "Using gpu device 0: GeForce GTX 1080 (CNMeM is disabled, cuDNN 5105)\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "import numpy as np\n", 40 | "from keras.models import Sequential\n", 41 | "from keras.layers.core import Dense, Lambda\n", 42 | "from keras import backend as K\n", 43 | "import matplotlib.pyplot as plt\n", 44 | "%matplotlib inline" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "# Parameters" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 2, 57 | "metadata": { 58 | "collapsed": true 59 | }, 60 | "outputs": [], 61 | "source": [ 62 | "k = 8 # number of information bits\n", 63 | "N = 16 # code length\n", 64 | "train_SNR_Eb = 1 # training-Eb/No\n", 65 | "\n", 66 | "nb_epoch = 2**16 # number of learning epochs\n", 67 | "code = 'polar' # type of code ('random' or 'polar')\n", 68 | "design = [128, 64, 32] # each list entry defines the number of nodes in a layer\n", 69 | "batch_size = 256 # size of batches for calculation the gradient\n", 70 | "LLR = False # 'True' enables the log-likelihood-ratio layer\n", 71 | "optimizer = 'adam' \n", 72 | "loss = 'mse' # or 'binary_crossentropy'\n", 73 | "\n", 74 | "train_SNR_Es = train_SNR_Eb + 10*np.log10(k/N)\n", 75 | "train_sigma = np.sqrt(1/(2*10**(train_SNR_Es/10)))" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "# Define NN model" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 3, 88 | "metadata": { 89 | "collapsed": true 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "def modulateBPSK(x):\n", 94 | " return -2*x +1;\n", 95 | "\n", 96 | "def addNoise(x, sigma):\n", 97 | " w = K.random_normal(K.shape(x), mean=0.0, std=sigma)\n", 98 | " return x + w\n", 99 | "\n", 100 | "def ber(y_true, y_pred):\n", 101 | " return K.mean(K.not_equal(y_true, K.round(y_pred)))\n", 102 | "\n", 103 | "def return_output_shape(input_shape): \n", 104 | " return input_shape\n", 105 | "\n", 106 | "def compose_model(layers):\n", 107 | " model = Sequential()\n", 108 | " for layer in layers:\n", 109 | " model.add(layer)\n", 110 | " return model\n", 111 | "\n", 112 | "def log_likelihood_ratio(x, sigma):\n", 113 | " return 2*x/np.float32(sigma**2)\n", 114 | "\n", 115 | "def errors(y_true, y_pred):\n", 116 | " return K.sum(K.not_equal(y_true, K.round(y_pred)))" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 4, 122 | "metadata": { 123 | "collapsed": false 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "# Define modulator\n", 128 | "modulator_layers = [Lambda(modulateBPSK, \n", 129 | " input_shape=(N,), output_shape=return_output_shape, name=\"modulator\")]\n", 130 | "modulator = compose_model(modulator_layers)\n", 131 | "modulator.compile(optimizer=optimizer, loss=loss)\n", 132 | "\n", 133 | "# Define noise\n", 134 | "noise_layers = [Lambda(addNoise, arguments={'sigma':train_sigma}, \n", 135 | " input_shape=(N,), output_shape=return_output_shape, name=\"noise\")]\n", 136 | "noise = compose_model(noise_layers)\n", 137 | "noise.compile(optimizer=optimizer, loss=loss)\n", 138 | "\n", 139 | "# Define LLR\n", 140 | "llr_layers = [Lambda(log_likelihood_ratio, arguments={'sigma':train_sigma}, \n", 141 | " input_shape=(N,), output_shape=return_output_shape, name=\"LLR\")]\n", 142 | "llr = compose_model(llr_layers)\n", 143 | "llr.compile(optimizer=optimizer, loss=loss)\n", 144 | "\n", 145 | "# Define decoder \n", 146 | "decoder_layers = [Dense(design[0], activation='relu', input_shape=(N,))]\n", 147 | "for i in range(1,len(design)):\n", 148 | " decoder_layers.append(Dense(design[i], activation='relu'))\n", 149 | "decoder_layers.append(Dense(k, activation='sigmoid'))\n", 150 | "decoder = compose_model(decoder_layers)\n", 151 | "decoder.compile(optimizer=optimizer, loss=loss, metrics=[errors])\n", 152 | "\n", 153 | "# Define model\n", 154 | "if LLR:\n", 155 | " model_layers = modulator_layers + noise_layers + llr_layers + decoder_layers\n", 156 | "else:\n", 157 | " model_layers = modulator_layers + noise_layers + decoder_layers\n", 158 | "model = compose_model(model_layers)\n", 159 | "model.compile(optimizer=optimizer, loss=loss, metrics=[ber])" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "# Data Generation" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 5, 172 | "metadata": { 173 | "collapsed": true 174 | }, 175 | "outputs": [], 176 | "source": [ 177 | "def half_adder(a,b):\n", 178 | " s = a ^ b\n", 179 | " c = a & b\n", 180 | " return s,c\n", 181 | "\n", 182 | "def full_adder(a,b,c):\n", 183 | " s = (a ^ b) ^ c\n", 184 | " c = (a & b) | (c & (a ^ b))\n", 185 | " return s,c\n", 186 | "\n", 187 | "def add_bool(a,b):\n", 188 | " if len(a) != len(b):\n", 189 | " raise ValueError('arrays with different length')\n", 190 | " k = len(a)\n", 191 | " s = np.zeros(k,dtype=bool)\n", 192 | " c = False\n", 193 | " for i in reversed(range(0,k)):\n", 194 | " s[i], c = full_adder(a[i],b[i],c) \n", 195 | " if c:\n", 196 | " warnings.warn(\"Addition overflow!\")\n", 197 | " return s\n", 198 | "\n", 199 | "def inc_bool(a):\n", 200 | " k = len(a)\n", 201 | " increment = np.hstack((np.zeros(k-1,dtype=bool), np.ones(1,dtype=bool)))\n", 202 | " a = add_bool(a,increment)\n", 203 | " return a\n", 204 | "\n", 205 | "def bitrevorder(x):\n", 206 | " m = np.amax(x)\n", 207 | " n = np.ceil(np.log2(m)).astype(int)\n", 208 | " for i in range(0,len(x)):\n", 209 | " x[i] = int('{:0{n}b}'.format(x[i],n=n)[::-1],2) \n", 210 | " return x\n", 211 | "\n", 212 | "def int2bin(x,N):\n", 213 | " if isinstance(x, list) or isinstance(x, np.ndarray):\n", 214 | " binary = np.zeros((len(x),N),dtype='bool')\n", 215 | " for i in range(0,len(x)):\n", 216 | " binary[i] = np.array([int(j) for j in bin(x[i])[2:].zfill(N)])\n", 217 | " else:\n", 218 | " binary = np.array([int(j) for j in bin(x)[2:].zfill(N)],dtype=bool)\n", 219 | " \n", 220 | " return binary\n", 221 | "\n", 222 | "def bin2int(b):\n", 223 | " if isinstance(b[0], list):\n", 224 | " integer = np.zeros((len(b),),dtype=int)\n", 225 | " for i in range(0,len(b)):\n", 226 | " out = 0\n", 227 | " for bit in b[i]:\n", 228 | " out = (out << 1) | bit\n", 229 | " integer[i] = out\n", 230 | " elif isinstance(b, np.ndarray):\n", 231 | " if len(b.shape) == 1:\n", 232 | " out = 0\n", 233 | " for bit in b:\n", 234 | " out = (out << 1) | bit\n", 235 | " integer = out \n", 236 | " else:\n", 237 | " integer = np.zeros((b.shape[0],),dtype=int)\n", 238 | " for i in range(0,b.shape[0]):\n", 239 | " out = 0\n", 240 | " for bit in b[i]:\n", 241 | " out = (out << 1) | bit\n", 242 | " integer[i] = out\n", 243 | " \n", 244 | " return integer\n", 245 | "\n", 246 | "def polar_design_awgn(N, k, design_snr_dB): \n", 247 | " \n", 248 | " S = 10**(design_snr_dB/10)\n", 249 | " z0 = np.zeros(N)\n", 250 | "\n", 251 | " z0[0] = np.exp(-S)\n", 252 | " for j in range(1,int(np.log2(N))+1):\n", 253 | " u = 2**j\n", 254 | " for t in range(0,int(u/2)):\n", 255 | " T = z0[t]\n", 256 | " z0[t] = 2*T - T**2 # upper channel\n", 257 | " z0[int(u/2)+t] = T**2 # lower channel\n", 258 | " \n", 259 | " # sort into increasing order\n", 260 | " idx = np.argsort(z0)\n", 261 | " \n", 262 | " # select k best channels\n", 263 | " idx = np.sort(bitrevorder(idx[0:k]))\n", 264 | " \n", 265 | " A = np.zeros(N, dtype=bool)\n", 266 | " A[idx] = True\n", 267 | " \n", 268 | " return A\n", 269 | "\n", 270 | "def polar_transform_iter(u):\n", 271 | "\n", 272 | " N = len(u)\n", 273 | " n = 1\n", 274 | " x = np.copy(u)\n", 275 | " stages = np.log2(N).astype(int)\n", 276 | " for s in range(0,stages):\n", 277 | " i = 0\n", 278 | " while i < N:\n", 279 | " for j in range(0,n):\n", 280 | " idx = i+j\n", 281 | " x[idx] = x[idx] ^ x[idx+n]\n", 282 | " i=i+2*n\n", 283 | " n=2*n\n", 284 | " return x" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 6, 290 | "metadata": { 291 | "collapsed": true 292 | }, 293 | "outputs": [], 294 | "source": [ 295 | "# Create all possible information words\n", 296 | "d = np.zeros((2**k,k),dtype=bool)\n", 297 | "for i in range(1,2**k):\n", 298 | " d[i]= inc_bool(d[i-1])\n", 299 | "\n", 300 | "# Create sets of all possible codewords (codebook)\n", 301 | "if code == 'polar': \n", 302 | " \n", 303 | " A = polar_design_awgn(N, k, design_snr_dB=0) # logical vector indicating the nonfrozen bit locations \n", 304 | " x = np.zeros((2**k, N),dtype=bool)\n", 305 | " u = np.zeros((2**k, N),dtype=bool)\n", 306 | " u[:,A] = d\n", 307 | "\n", 308 | " for i in range(0,2**k):\n", 309 | " x[i] = polar_transform_iter(u[i])\n", 310 | "\n", 311 | "elif code == 'random':\n", 312 | " \n", 313 | " np.random.seed(4267) # for a 16bit Random Code (r=0.5) with Hamming distance >= 2\n", 314 | " x = np.random.randint(0,2,size=(2**k,N), dtype=bool)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "# Train Neural Network" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 7, 327 | "metadata": { 328 | "collapsed": false 329 | }, 330 | "outputs": [ 331 | { 332 | "name": "stdout", 333 | "output_type": "stream", 334 | "text": [ 335 | "____________________________________________________________________________________________________\n", 336 | "Layer (type) Output Shape Param # Connected to \n", 337 | "====================================================================================================\n", 338 | "modulator (Lambda) (None, 16) 0 lambda_input_1[0][0] \n", 339 | "____________________________________________________________________________________________________\n", 340 | "noise (Lambda) (None, 16) 0 modulator[0][0] \n", 341 | "____________________________________________________________________________________________________\n", 342 | "dense_1 (Dense) (None, 128) 2176 noise[1][0] \n", 343 | "____________________________________________________________________________________________________\n", 344 | "dense_2 (Dense) (None, 64) 8256 dense_1[1][0] \n", 345 | "____________________________________________________________________________________________________\n", 346 | "dense_3 (Dense) (None, 32) 2080 dense_2[1][0] \n", 347 | "____________________________________________________________________________________________________\n", 348 | "dense_4 (Dense) (None, 8) 264 dense_3[1][0] \n", 349 | "====================================================================================================\n", 350 | "Total params: 12776\n", 351 | "____________________________________________________________________________________________________\n" 352 | ] 353 | } 354 | ], 355 | "source": [ 356 | "model.summary()\n", 357 | "history = model.fit(x, d, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0, shuffle=True)" 358 | ] 359 | }, 360 | { 361 | "cell_type": "markdown", 362 | "metadata": {}, 363 | "source": [ 364 | "# Test NN" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 8, 370 | "metadata": { 371 | "collapsed": true 372 | }, 373 | "outputs": [], 374 | "source": [ 375 | "test_batch = 1000 \n", 376 | "num_words = 100000 # multiple of test_batch\n", 377 | "\n", 378 | "SNR_dB_start_Eb = 0\n", 379 | "SNR_dB_stop_Eb = 5\n", 380 | "SNR_points = 20" 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": 9, 386 | "metadata": { 387 | "collapsed": false 388 | }, 389 | "outputs": [], 390 | "source": [ 391 | "SNR_dB_start_Es = SNR_dB_start_Eb + 10*np.log10(k/N)\n", 392 | "SNR_dB_stop_Es = SNR_dB_stop_Eb + 10*np.log10(k/N)\n", 393 | "\n", 394 | "sigma_start = np.sqrt(1/(2*10**(SNR_dB_start_Es/10)))\n", 395 | "sigma_stop = np.sqrt(1/(2*10**(SNR_dB_stop_Es/10)))\n", 396 | "\n", 397 | "sigmas = np.linspace(sigma_start, sigma_stop, SNR_points)\n", 398 | "\n", 399 | "nb_errors = np.zeros(len(sigmas),dtype=int)\n", 400 | "nb_bits = np.zeros(len(sigmas),dtype=int)\n", 401 | "\n", 402 | "for i in range(0,len(sigmas)):\n", 403 | "\n", 404 | " for ii in range(0,np.round(num_words/test_batch).astype(int)):\n", 405 | " \n", 406 | " # Source\n", 407 | " np.random.seed(0)\n", 408 | " d_test = np.random.randint(0,2,size=(test_batch,k)) \n", 409 | "\n", 410 | " # Encoder\n", 411 | " if code == 'polar':\n", 412 | " x_test = np.zeros((test_batch, N),dtype=bool)\n", 413 | " u_test = np.zeros((test_batch, N),dtype=bool)\n", 414 | " u_test[:,A] = d_test\n", 415 | "\n", 416 | " for iii in range(0,test_batch):\n", 417 | " x_test[iii] = polar_transform_iter(u_test[iii])\n", 418 | "\n", 419 | " elif code == 'random':\n", 420 | " x_test = np.zeros((test_batch, N),dtype=bool)\n", 421 | " for iii in range(0,test_batch):\n", 422 | " x_test[iii] = x[bin2int(d_test[iii])]\n", 423 | "\n", 424 | " # Modulator (BPSK)\n", 425 | " s_test = -2*x_test + 1\n", 426 | "\n", 427 | " # Channel (AWGN)\n", 428 | " y_test = s_test + sigmas[i]*np.random.standard_normal(s_test.shape)\n", 429 | "\n", 430 | " if LLR:\n", 431 | " y_test = 2*y_test/(sigmas[i]**2)\n", 432 | "\n", 433 | " # Decoder\n", 434 | " nb_errors[i] += decoder.evaluate(y_test, d_test, batch_size=test_batch, verbose=0)[1]\n", 435 | " nb_bits[i] += d_test.size" 436 | ] 437 | }, 438 | { 439 | "cell_type": "markdown", 440 | "metadata": {}, 441 | "source": [ 442 | "# Load MAP" 443 | ] 444 | }, 445 | { 446 | "cell_type": "code", 447 | "execution_count": 10, 448 | "metadata": { 449 | "collapsed": true 450 | }, 451 | "outputs": [], 452 | "source": [ 453 | "result_map = np.loadtxt('map/{}/results_{}_map_{}_{}.txt'.format(code,code,N,k), delimiter=', ')\n", 454 | "sigmas_map = result_map[:,0]\n", 455 | "nb_bits_map = result_map[:,1]\n", 456 | "nb_errors_map = result_map[:,2]" 457 | ] 458 | }, 459 | { 460 | "cell_type": "markdown", 461 | "metadata": {}, 462 | "source": [ 463 | "# Plot Bit-Error-Rate" 464 | ] 465 | }, 466 | { 467 | "cell_type": "code", 468 | "execution_count": 11, 469 | "metadata": { 470 | "collapsed": false 471 | }, 472 | "outputs": [ 473 | { 474 | "data": { 475 | "image/png": "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\n", 476 | "text/plain": [ 477 | "" 478 | ] 479 | }, 480 | "metadata": {}, 481 | "output_type": "display_data" 482 | } 483 | ], 484 | "source": [ 485 | "legend = []\n", 486 | "\n", 487 | "plt.plot(10*np.log10(1/(2*sigmas**2)) - 10*np.log10(k/N), nb_errors/nb_bits)\n", 488 | "legend.append('NN') \n", 489 | "\n", 490 | "plt.plot(10*np.log10(1/(2*sigmas_map**2)) - 10*np.log10(k/N), nb_errors_map/nb_bits_map)\n", 491 | "legend.append('MAP') \n", 492 | "\n", 493 | "plt.legend(legend, loc=3)\n", 494 | "plt.yscale('log')\n", 495 | "plt.xlabel('$E_b/N_0$')\n", 496 | "plt.ylabel('BER') \n", 497 | "plt.grid(True)\n", 498 | "plt.show()" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": null, 504 | "metadata": { 505 | "collapsed": true 506 | }, 507 | "outputs": [], 508 | "source": [] 509 | } 510 | ], 511 | "metadata": { 512 | "kernelspec": { 513 | "display_name": "Python 3", 514 | "language": "python", 515 | "name": "python3" 516 | }, 517 | "language_info": { 518 | "codemirror_mode": { 519 | "name": "ipython", 520 | "version": 3 521 | }, 522 | "file_extension": ".py", 523 | "mimetype": "text/x-python", 524 | "name": "python", 525 | "nbconvert_exporter": "python", 526 | "pygments_lexer": "ipython3", 527 | "version": "3.4.3" 528 | } 529 | }, 530 | "nbformat": 4, 531 | "nbformat_minor": 1 532 | } 533 | -------------------------------------------------------------------------------- /notebooks/On Deep Learning-Based Channel Decoding.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# On Deep Learning-Based Channel Decoding\n", 8 | "\n", 9 | "If you want to cite this notebook, please use the following bibtext entry:\n", 10 | "\n", 11 | " @article{nn-decoding,\n", 12 | " title={On Deep Learning-Based Channel Decoding},\n", 13 | " author={Tobias Gruber and\n", 14 | " Sebastian Cammerer and\n", 15 | " Jakob Hoydis and\n", 16 | " Stephan ten Brink}\n", 17 | " journal={CoRR}\n", 18 | " year={2017}\n", 19 | " url= {http://arxiv.org/abs/1701.07738}\n", 20 | " }\n", 21 | "\n", 22 | "Running this example requires Keras installed with the Theano backend. For GPU support nvidia-docker is required. A Dockerfile is provided to employ this setup quickly.\n", 23 | "\n", 24 | "Our simulation setup was inspired by material from http://radioml.org.\n" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "metadata": { 31 | "collapsed": false 32 | }, 33 | "outputs": [ 34 | { 35 | "name": "stderr", 36 | "output_type": "stream", 37 | "text": [ 38 | "Using Theano backend.\n", 39 | "Using gpu device 0: GeForce GTX 1080 (CNMeM is disabled, cuDNN 5105)\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "import numpy as np\n", 45 | "from keras.models import Sequential\n", 46 | "from keras.layers.core import Dense, Lambda\n", 47 | "from keras import backend as K\n", 48 | "import matplotlib.pyplot as plt\n", 49 | "%matplotlib inline" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "# Parameters" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 2, 62 | "metadata": { 63 | "collapsed": true 64 | }, 65 | "outputs": [], 66 | "source": [ 67 | "k = 8 # number of information bits\n", 68 | "N = 16 # code length\n", 69 | "train_SNR_Eb = 1 # training-Eb/No\n", 70 | "\n", 71 | "nb_epoch = 2**16 # number of learning epochs\n", 72 | "code = 'polar' # type of code ('random' or 'polar')\n", 73 | "design = [128, 64, 32] # each list entry defines the number of nodes in a layer\n", 74 | "batch_size = 256 # size of batches for calculation the gradient\n", 75 | "LLR = False # 'True' enables the log-likelihood-ratio layer\n", 76 | "optimizer = 'adam' \n", 77 | "loss = 'mse' # or 'binary_crossentropy'\n", 78 | "\n", 79 | "train_SNR_Es = train_SNR_Eb + 10*np.log10(k/N)\n", 80 | "train_sigma = np.sqrt(1/(2*10**(train_SNR_Es/10)))" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "# Define NN model" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 3, 93 | "metadata": { 94 | "collapsed": true 95 | }, 96 | "outputs": [], 97 | "source": [ 98 | "def modulateBPSK(x):\n", 99 | " return -2*x +1;\n", 100 | "\n", 101 | "def addNoise(x, sigma):\n", 102 | " w = K.random_normal(K.shape(x), mean=0.0, std=sigma)\n", 103 | " return x + w\n", 104 | "\n", 105 | "def ber(y_true, y_pred):\n", 106 | " return K.mean(K.not_equal(y_true, K.round(y_pred)))\n", 107 | "\n", 108 | "def return_output_shape(input_shape): \n", 109 | " return input_shape\n", 110 | "\n", 111 | "def compose_model(layers):\n", 112 | " model = Sequential()\n", 113 | " for layer in layers:\n", 114 | " model.add(layer)\n", 115 | " return model\n", 116 | "\n", 117 | "def log_likelihood_ratio(x, sigma):\n", 118 | " return 2*x/np.float32(sigma**2)\n", 119 | "\n", 120 | "def errors(y_true, y_pred):\n", 121 | " return K.sum(K.not_equal(y_true, K.round(y_pred)))" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 4, 127 | "metadata": { 128 | "collapsed": false 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "# Define modulator\n", 133 | "modulator_layers = [Lambda(modulateBPSK, \n", 134 | " input_shape=(N,), output_shape=return_output_shape, name=\"modulator\")]\n", 135 | "modulator = compose_model(modulator_layers)\n", 136 | "modulator.compile(optimizer=optimizer, loss=loss)\n", 137 | "\n", 138 | "# Define noise\n", 139 | "noise_layers = [Lambda(addNoise, arguments={'sigma':train_sigma}, \n", 140 | " input_shape=(N,), output_shape=return_output_shape, name=\"noise\")]\n", 141 | "noise = compose_model(noise_layers)\n", 142 | "noise.compile(optimizer=optimizer, loss=loss)\n", 143 | "\n", 144 | "# Define LLR\n", 145 | "llr_layers = [Lambda(log_likelihood_ratio, arguments={'sigma':train_sigma}, \n", 146 | " input_shape=(N,), output_shape=return_output_shape, name=\"LLR\")]\n", 147 | "llr = compose_model(llr_layers)\n", 148 | "llr.compile(optimizer=optimizer, loss=loss)\n", 149 | "\n", 150 | "# Define decoder \n", 151 | "decoder_layers = [Dense(design[0], activation='relu', input_shape=(N,))]\n", 152 | "for i in range(1,len(design)):\n", 153 | " decoder_layers.append(Dense(design[i], activation='relu'))\n", 154 | "decoder_layers.append(Dense(k, activation='sigmoid'))\n", 155 | "decoder = compose_model(decoder_layers)\n", 156 | "decoder.compile(optimizer=optimizer, loss=loss, metrics=[errors])\n", 157 | "\n", 158 | "# Define model\n", 159 | "if LLR:\n", 160 | " model_layers = modulator_layers + noise_layers + llr_layers + decoder_layers\n", 161 | "else:\n", 162 | " model_layers = modulator_layers + noise_layers + decoder_layers\n", 163 | "model = compose_model(model_layers)\n", 164 | "model.compile(optimizer=optimizer, loss=loss, metrics=[ber])" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "# Data Generation" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": 5, 177 | "metadata": { 178 | "collapsed": true 179 | }, 180 | "outputs": [], 181 | "source": [ 182 | "def half_adder(a,b):\n", 183 | " s = a ^ b\n", 184 | " c = a & b\n", 185 | " return s,c\n", 186 | "\n", 187 | "def full_adder(a,b,c):\n", 188 | " s = (a ^ b) ^ c\n", 189 | " c = (a & b) | (c & (a ^ b))\n", 190 | " return s,c\n", 191 | "\n", 192 | "def add_bool(a,b):\n", 193 | " if len(a) != len(b):\n", 194 | " raise ValueError('arrays with different length')\n", 195 | " k = len(a)\n", 196 | " s = np.zeros(k,dtype=bool)\n", 197 | " c = False\n", 198 | " for i in reversed(range(0,k)):\n", 199 | " s[i], c = full_adder(a[i],b[i],c) \n", 200 | " if c:\n", 201 | " warnings.warn(\"Addition overflow!\")\n", 202 | " return s\n", 203 | "\n", 204 | "def inc_bool(a):\n", 205 | " k = len(a)\n", 206 | " increment = np.hstack((np.zeros(k-1,dtype=bool), np.ones(1,dtype=bool)))\n", 207 | " a = add_bool(a,increment)\n", 208 | " return a\n", 209 | "\n", 210 | "def bitrevorder(x):\n", 211 | " m = np.amax(x)\n", 212 | " n = np.ceil(np.log2(m)).astype(int)\n", 213 | " for i in range(0,len(x)):\n", 214 | " x[i] = int('{:0{n}b}'.format(x[i],n=n)[::-1],2) \n", 215 | " return x\n", 216 | "\n", 217 | "def int2bin(x,N):\n", 218 | " if isinstance(x, list) or isinstance(x, np.ndarray):\n", 219 | " binary = np.zeros((len(x),N),dtype='bool')\n", 220 | " for i in range(0,len(x)):\n", 221 | " binary[i] = np.array([int(j) for j in bin(x[i])[2:].zfill(N)])\n", 222 | " else:\n", 223 | " binary = np.array([int(j) for j in bin(x)[2:].zfill(N)],dtype=bool)\n", 224 | " \n", 225 | " return binary\n", 226 | "\n", 227 | "def bin2int(b):\n", 228 | " if isinstance(b[0], list):\n", 229 | " integer = np.zeros((len(b),),dtype=int)\n", 230 | " for i in range(0,len(b)):\n", 231 | " out = 0\n", 232 | " for bit in b[i]:\n", 233 | " out = (out << 1) | bit\n", 234 | " integer[i] = out\n", 235 | " elif isinstance(b, np.ndarray):\n", 236 | " if len(b.shape) == 1:\n", 237 | " out = 0\n", 238 | " for bit in b:\n", 239 | " out = (out << 1) | bit\n", 240 | " integer = out \n", 241 | " else:\n", 242 | " integer = np.zeros((b.shape[0],),dtype=int)\n", 243 | " for i in range(0,b.shape[0]):\n", 244 | " out = 0\n", 245 | " for bit in b[i]:\n", 246 | " out = (out << 1) | bit\n", 247 | " integer[i] = out\n", 248 | " \n", 249 | " return integer\n", 250 | "\n", 251 | "def polar_design_awgn(N, k, design_snr_dB): \n", 252 | " \n", 253 | " S = 10**(design_snr_dB/10)\n", 254 | " z0 = np.zeros(N)\n", 255 | "\n", 256 | " z0[0] = np.exp(-S)\n", 257 | " for j in range(1,int(np.log2(N))+1):\n", 258 | " u = 2**j\n", 259 | " for t in range(0,int(u/2)):\n", 260 | " T = z0[t]\n", 261 | " z0[t] = 2*T - T**2 # upper channel\n", 262 | " z0[int(u/2)+t] = T**2 # lower channel\n", 263 | " \n", 264 | " # sort into increasing order\n", 265 | " idx = np.argsort(z0)\n", 266 | " \n", 267 | " # select k best channels\n", 268 | " idx = np.sort(bitrevorder(idx[0:k]))\n", 269 | " \n", 270 | " A = np.zeros(N, dtype=bool)\n", 271 | " A[idx] = True\n", 272 | " \n", 273 | " return A\n", 274 | "\n", 275 | "def polar_transform_iter(u):\n", 276 | "\n", 277 | " N = len(u)\n", 278 | " n = 1\n", 279 | " x = np.copy(u)\n", 280 | " stages = np.log2(N).astype(int)\n", 281 | " for s in range(0,stages):\n", 282 | " i = 0\n", 283 | " while i < N:\n", 284 | " for j in range(0,n):\n", 285 | " idx = i+j\n", 286 | " x[idx] = x[idx] ^ x[idx+n]\n", 287 | " i=i+2*n\n", 288 | " n=2*n\n", 289 | " return x" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 6, 295 | "metadata": { 296 | "collapsed": true 297 | }, 298 | "outputs": [], 299 | "source": [ 300 | "# Create all possible information words\n", 301 | "d = np.zeros((2**k,k),dtype=bool)\n", 302 | "for i in range(1,2**k):\n", 303 | " d[i]= inc_bool(d[i-1])\n", 304 | "\n", 305 | "# Create sets of all possible codewords (codebook)\n", 306 | "if code == 'polar': \n", 307 | " \n", 308 | " A = polar_design_awgn(N, k, design_snr_dB=0) # logical vector indicating the nonfrozen bit locations \n", 309 | " x = np.zeros((2**k, N),dtype=bool)\n", 310 | " u = np.zeros((2**k, N),dtype=bool)\n", 311 | " u[:,A] = d\n", 312 | "\n", 313 | " for i in range(0,2**k):\n", 314 | " x[i] = polar_transform_iter(u[i])\n", 315 | "\n", 316 | "elif code == 'random':\n", 317 | " \n", 318 | " np.random.seed(4267) # for a 16bit Random Code (r=0.5) with Hamming distance >= 2\n", 319 | " x = np.random.randint(0,2,size=(2**k,N), dtype=bool)" 320 | ] 321 | }, 322 | { 323 | "cell_type": "markdown", 324 | "metadata": {}, 325 | "source": [ 326 | "# Train Neural Network" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 7, 332 | "metadata": { 333 | "collapsed": false 334 | }, 335 | "outputs": [ 336 | { 337 | "name": "stdout", 338 | "output_type": "stream", 339 | "text": [ 340 | "____________________________________________________________________________________________________\n", 341 | "Layer (type) Output Shape Param # Connected to \n", 342 | "====================================================================================================\n", 343 | "modulator (Lambda) (None, 16) 0 lambda_input_1[0][0] \n", 344 | "____________________________________________________________________________________________________\n", 345 | "noise (Lambda) (None, 16) 0 modulator[0][0] \n", 346 | "____________________________________________________________________________________________________\n", 347 | "dense_1 (Dense) (None, 128) 2176 noise[1][0] \n", 348 | "____________________________________________________________________________________________________\n", 349 | "dense_2 (Dense) (None, 64) 8256 dense_1[1][0] \n", 350 | "____________________________________________________________________________________________________\n", 351 | "dense_3 (Dense) (None, 32) 2080 dense_2[1][0] \n", 352 | "____________________________________________________________________________________________________\n", 353 | "dense_4 (Dense) (None, 8) 264 dense_3[1][0] \n", 354 | "====================================================================================================\n", 355 | "Total params: 12776\n", 356 | "____________________________________________________________________________________________________\n" 357 | ] 358 | } 359 | ], 360 | "source": [ 361 | "model.summary()\n", 362 | "history = model.fit(x, d, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0, shuffle=True)" 363 | ] 364 | }, 365 | { 366 | "cell_type": "markdown", 367 | "metadata": {}, 368 | "source": [ 369 | "# Test NN" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 8, 375 | "metadata": { 376 | "collapsed": true 377 | }, 378 | "outputs": [], 379 | "source": [ 380 | "test_batch = 1000 \n", 381 | "num_words = 100000 # multiple of test_batch\n", 382 | "\n", 383 | "SNR_dB_start_Eb = 0\n", 384 | "SNR_dB_stop_Eb = 5\n", 385 | "SNR_points = 20" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": 9, 391 | "metadata": { 392 | "collapsed": false 393 | }, 394 | "outputs": [], 395 | "source": [ 396 | "SNR_dB_start_Es = SNR_dB_start_Eb + 10*np.log10(k/N)\n", 397 | "SNR_dB_stop_Es = SNR_dB_stop_Eb + 10*np.log10(k/N)\n", 398 | "\n", 399 | "sigma_start = np.sqrt(1/(2*10**(SNR_dB_start_Es/10)))\n", 400 | "sigma_stop = np.sqrt(1/(2*10**(SNR_dB_stop_Es/10)))\n", 401 | "\n", 402 | "sigmas = np.linspace(sigma_start, sigma_stop, SNR_points)\n", 403 | "\n", 404 | "nb_errors = np.zeros(len(sigmas),dtype=int)\n", 405 | "nb_bits = np.zeros(len(sigmas),dtype=int)\n", 406 | "\n", 407 | "for i in range(0,len(sigmas)):\n", 408 | "\n", 409 | " for ii in range(0,np.round(num_words/test_batch).astype(int)):\n", 410 | " \n", 411 | " # Source\n", 412 | " np.random.seed(0)\n", 413 | " d_test = np.random.randint(0,2,size=(test_batch,k)) \n", 414 | "\n", 415 | " # Encoder\n", 416 | " if code == 'polar':\n", 417 | " x_test = np.zeros((test_batch, N),dtype=bool)\n", 418 | " u_test = np.zeros((test_batch, N),dtype=bool)\n", 419 | " u_test[:,A] = d_test\n", 420 | "\n", 421 | " for iii in range(0,test_batch):\n", 422 | " x_test[iii] = polar_transform_iter(u_test[iii])\n", 423 | "\n", 424 | " elif code == 'random':\n", 425 | " x_test = np.zeros((test_batch, N),dtype=bool)\n", 426 | " for iii in range(0,test_batch):\n", 427 | " x_test[iii] = x[bin2int(d_test[iii])]\n", 428 | "\n", 429 | " # Modulator (BPSK)\n", 430 | " s_test = -2*x_test + 1\n", 431 | "\n", 432 | " # Channel (AWGN)\n", 433 | " y_test = s_test + sigmas[i]*np.random.standard_normal(s_test.shape)\n", 434 | "\n", 435 | " if LLR:\n", 436 | " y_test = 2*y_test/(sigmas[i]**2)\n", 437 | "\n", 438 | " # Decoder\n", 439 | " nb_errors[i] += decoder.evaluate(y_test, d_test, batch_size=test_batch, verbose=0)[1]\n", 440 | " nb_bits[i] += d_test.size" 441 | ] 442 | }, 443 | { 444 | "cell_type": "markdown", 445 | "metadata": {}, 446 | "source": [ 447 | "# Load MAP" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 10, 453 | "metadata": { 454 | "collapsed": true 455 | }, 456 | "outputs": [], 457 | "source": [ 458 | "result_map = np.loadtxt('map/{}/results_{}_map_{}_{}.txt'.format(code,code,N,k), delimiter=', ')\n", 459 | "sigmas_map = result_map[:,0]\n", 460 | "nb_bits_map = result_map[:,1]\n", 461 | "nb_errors_map = result_map[:,2]" 462 | ] 463 | }, 464 | { 465 | "cell_type": "markdown", 466 | "metadata": {}, 467 | "source": [ 468 | "# Plot Bit-Error-Rate" 469 | ] 470 | }, 471 | { 472 | "cell_type": "code", 473 | "execution_count": 11, 474 | "metadata": { 475 | "collapsed": false 476 | }, 477 | "outputs": [ 478 | { 479 | "data": { 480 | "image/png": "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\n", 481 | "text/plain": [ 482 | "" 483 | ] 484 | }, 485 | "metadata": {}, 486 | "output_type": "display_data" 487 | } 488 | ], 489 | "source": [ 490 | "legend = []\n", 491 | "\n", 492 | "plt.plot(10*np.log10(1/(2*sigmas**2)) - 10*np.log10(k/N), nb_errors/nb_bits)\n", 493 | "legend.append('NN') \n", 494 | "\n", 495 | "plt.plot(10*np.log10(1/(2*sigmas_map**2)) - 10*np.log10(k/N), nb_errors_map/nb_bits_map)\n", 496 | "legend.append('MAP') \n", 497 | "\n", 498 | "plt.legend(legend, loc=3)\n", 499 | "plt.yscale('log')\n", 500 | "plt.xlabel('$E_b/N_0$')\n", 501 | "plt.ylabel('BER') \n", 502 | "plt.grid(True)\n", 503 | "plt.show()" 504 | ] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "execution_count": null, 509 | "metadata": { 510 | "collapsed": true 511 | }, 512 | "outputs": [], 513 | "source": [] 514 | } 515 | ], 516 | "metadata": { 517 | "kernelspec": { 518 | "display_name": "Python 3", 519 | "language": "python", 520 | "name": "python3" 521 | }, 522 | "language_info": { 523 | "codemirror_mode": { 524 | "name": "ipython", 525 | "version": 3 526 | }, 527 | "file_extension": ".py", 528 | "mimetype": "text/x-python", 529 | "name": "python", 530 | "nbconvert_exporter": "python", 531 | "pygments_lexer": "ipython3", 532 | "version": "3.4.3" 533 | } 534 | }, 535 | "nbformat": 4, 536 | "nbformat_minor": 1 537 | } 538 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_1.txt: -------------------------------------------------------------------------------- 1 | 2.828427, 100000, 7900, 100000, 7900 2 | 2.763275, 100000, 7325, 100000, 7325 3 | 2.698123, 100000, 6873, 100000, 6873 4 | 2.632971, 100000, 6536, 100000, 6536 5 | 2.567820, 100000, 5878, 100000, 5878 6 | 2.502668, 100000, 5581, 100000, 5581 7 | 2.437516, 100000, 5033, 100000, 5033 8 | 2.372364, 100000, 4722, 100000, 4722 9 | 2.307212, 100000, 4131, 100000, 4131 10 | 2.242060, 100000, 3678, 100000, 3678 11 | 2.176908, 100000, 3356, 100000, 3356 12 | 2.111756, 100000, 2837, 100000, 2837 13 | 2.046605, 100000, 2529, 100000, 2529 14 | 1.981453, 100000, 2098, 100000, 2098 15 | 1.916301, 100000, 1918, 100000, 1918 16 | 1.851149, 100000, 1548, 100000, 1548 17 | 1.785997, 100000, 1302, 100000, 1302 18 | 1.720845, 100000, 972, 100000, 972 19 | 1.655693, 100000, 791, 100000, 791 20 | 1.590541, 100000, 599, 100000, 599 21 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_2.txt: -------------------------------------------------------------------------------- 1 | 2.000000, 200000, 22277, 100000, 15081 2 | 1.953931, 200000, 21188, 100000, 14239 3 | 1.907861, 200000, 19690, 100000, 13224 4 | 1.861792, 200000, 18313, 100000, 12338 5 | 1.815723, 200000, 17158, 100000, 11485 6 | 1.769653, 200000, 15750, 100000, 10558 7 | 1.723584, 200000, 14617, 100000, 9831 8 | 1.677515, 200000, 13373, 100000, 8974 9 | 1.631445, 200000, 11887, 100000, 7983 10 | 1.585376, 200000, 10913, 100000, 7323 11 | 1.539307, 200000, 9628, 100000, 6448 12 | 1.493237, 200000, 8502, 100000, 5706 13 | 1.447168, 200000, 7476, 100000, 4972 14 | 1.401099, 200000, 6424, 100000, 4292 15 | 1.355029, 200000, 5389, 100000, 3611 16 | 1.308960, 200000, 4604, 100000, 3069 17 | 1.262891, 200000, 3684, 100000, 2490 18 | 1.216821, 200000, 2986, 100000, 1976 19 | 1.170752, 200000, 2290, 100000, 1526 20 | 1.124683, 200000, 1822, 100000, 1216 21 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_3.txt: -------------------------------------------------------------------------------- 1 | 1.632993, 300000, 30160, 100000, 16434 2 | 1.595378, 300000, 28299, 100000, 15486 3 | 1.557762, 300000, 25955, 100000, 14161 4 | 1.520147, 300000, 23893, 100000, 13000 5 | 1.482531, 300000, 21529, 100000, 11789 6 | 1.444916, 300000, 19471, 100000, 10628 7 | 1.407300, 300000, 17742, 100000, 9703 8 | 1.369685, 300000, 15879, 100000, 8660 9 | 1.332070, 300000, 13889, 100000, 7589 10 | 1.294454, 300000, 11812, 100000, 6467 11 | 1.256839, 300000, 10457, 100000, 5714 12 | 1.219223, 300000, 8521, 100000, 4677 13 | 1.181608, 300000, 7208, 100000, 3931 14 | 1.143992, 300000, 5976, 100000, 3269 15 | 1.106377, 300000, 4727, 100000, 2613 16 | 1.068761, 300000, 3826, 100000, 2077 17 | 1.031146, 300000, 2797, 100000, 1521 18 | 0.993530, 300000, 2143, 100000, 1171 19 | 0.955915, 300000, 1459, 100000, 786 20 | 0.918300, 300000, 987, 100000, 553 21 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_4.txt: -------------------------------------------------------------------------------- 1 | 1.414214, 400000, 35976, 100000, 16185 2 | 1.381638, 400000, 33370, 100000, 15138 3 | 1.349062, 400000, 30231, 100000, 13613 4 | 1.316486, 400000, 27534, 100000, 12399 5 | 1.283910, 400000, 24252, 100000, 10969 6 | 1.251334, 400000, 21319, 100000, 9621 7 | 1.218758, 400000, 19192, 100000, 8637 8 | 1.186182, 400000, 16877, 100000, 7631 9 | 1.153606, 400000, 13659, 100000, 6170 10 | 1.121030, 400000, 11874, 100000, 5383 11 | 1.088454, 400000, 9657, 100000, 4388 12 | 1.055878, 400000, 7798, 100000, 3499 13 | 1.023302, 400000, 6075, 100000, 2760 14 | 0.990726, 400000, 4834, 100000, 2167 15 | 0.958150, 400000, 3745, 100000, 1688 16 | 0.925574, 400000, 2744, 100000, 1220 17 | 0.892999, 400000, 1966, 100000, 885 18 | 0.860423, 400000, 1283, 100000, 582 19 | 0.827847, 400000, 783, 100000, 356 20 | 0.795271, 400000, 521, 100000, 237 21 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_5.txt: -------------------------------------------------------------------------------- 1 | 1.264911, 500000, 41361, 100000, 15627 2 | 1.235774, 500000, 37638, 100000, 14318 3 | 1.206637, 500000, 33450, 100000, 12683 4 | 1.177501, 500000, 30165, 100000, 11417 5 | 1.148364, 500000, 26327, 100000, 9999 6 | 1.119227, 500000, 22451, 100000, 8555 7 | 1.090090, 500000, 19475, 100000, 7382 8 | 1.060953, 500000, 16085, 100000, 6107 9 | 1.031817, 500000, 13510, 100000, 5164 10 | 1.002680, 500000, 11345, 100000, 4284 11 | 0.973543, 500000, 8983, 100000, 3410 12 | 0.944406, 500000, 6760, 100000, 2549 13 | 0.915269, 500000, 5055, 100000, 1893 14 | 0.886133, 500000, 3810, 100000, 1445 15 | 0.856996, 500000, 2771, 100000, 1032 16 | 0.827859, 500000, 1983, 100000, 732 17 | 0.798722, 500000, 1240, 100000, 475 18 | 0.769585, 500000, 729, 100000, 277 19 | 0.740449, 500000, 377, 100000, 152 20 | 0.711312, 500000, 208, 100000, 85 21 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_6.txt: -------------------------------------------------------------------------------- 1 | 1.154701, 600000, 58422, 100000, 21527 2 | 1.128102, 600000, 53755, 100000, 19912 3 | 1.101504, 600000, 47818, 100000, 17855 4 | 1.074906, 600000, 43462, 100000, 16318 5 | 1.048308, 600000, 39378, 100000, 14788 6 | 1.021710, 600000, 33501, 100000, 12818 7 | 0.995112, 600000, 29559, 100000, 11317 8 | 0.968514, 600000, 25315, 100000, 9760 9 | 0.941915, 600000, 22143, 100000, 8599 10 | 0.915317, 600000, 18090, 100000, 7121 11 | 0.888719, 600000, 15224, 100000, 6016 12 | 0.862121, 600000, 12098, 100000, 4875 13 | 0.835523, 600000, 9659, 100000, 3938 14 | 0.808925, 600000, 7543, 100000, 3055 15 | 0.782327, 600000, 5628, 100000, 2303 16 | 0.755728, 600000, 4361, 100000, 1805 17 | 0.729130, 600000, 3356, 100000, 1405 18 | 0.702532, 600000, 2201, 100000, 942 19 | 0.675934, 600000, 1597, 100000, 674 20 | 0.649336, 600000, 982, 100000, 445 21 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_7.txt: -------------------------------------------------------------------------------- 1 | 1.069045, 700000, 78305, 100000, 26375 2 | 1.044420, 700000, 71963, 100000, 24128 3 | 1.019795, 700000, 64419, 100000, 21943 4 | 0.995170, 700000, 58909, 100000, 19930 5 | 0.970545, 700000, 53274, 100000, 18123 6 | 0.945919, 700000, 45698, 100000, 15774 7 | 0.921294, 700000, 40631, 100000, 14090 8 | 0.896669, 700000, 36352, 100000, 12521 9 | 0.872044, 700000, 30593, 100000, 10633 10 | 0.847419, 700000, 26136, 100000, 9098 11 | 0.822794, 700000, 21442, 100000, 7487 12 | 0.798169, 700000, 17560, 100000, 6162 13 | 0.773544, 700000, 14035, 100000, 4972 14 | 0.748919, 700000, 10878, 100000, 3874 15 | 0.724294, 700000, 8255, 100000, 2946 16 | 0.699669, 700000, 6423, 100000, 2267 17 | 0.675043, 700000, 4682, 100000, 1702 18 | 0.650418, 700000, 3137, 100000, 1160 19 | 0.625793, 700000, 1975, 100000, 706 20 | 0.601168, 700000, 1345, 100000, 507 21 | -------------------------------------------------------------------------------- /notebooks/map/polar/results_polar_map_16_8.txt: -------------------------------------------------------------------------------- 1 | 1.000000, 800000, 99463, 100000, 29498 2 | 0.976965, 800000, 92809, 100000, 27316 3 | 0.953931, 800000, 84622, 100000, 25020 4 | 0.930896, 800000, 76647, 100000, 22735 5 | 0.907861, 800000, 68530, 100000, 20458 6 | 0.884827, 800000, 60749, 100000, 18207 7 | 0.861792, 800000, 53272, 100000, 16016 8 | 0.838757, 800000, 47885, 100000, 14211 9 | 0.815723, 800000, 39644, 100000, 11931 10 | 0.792688, 800000, 33407, 100000, 10081 11 | 0.769653, 800000, 27958, 100000, 8480 12 | 0.746619, 800000, 22746, 100000, 6965 13 | 0.723584, 800000, 18070, 100000, 5490 14 | 0.700549, 800000, 14290, 100000, 4322 15 | 0.677515, 800000, 10778, 100000, 3284 16 | 0.654480, 800000, 7794, 100000, 2383 17 | 0.631445, 800000, 5532, 100000, 1737 18 | 0.608411, 800000, 4057, 100000, 1209 19 | 0.585376, 800000, 2407, 100000, 725 20 | 0.562341, 800000, 1396, 100000, 438 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_1.txt: -------------------------------------------------------------------------------- 1 | 2.828427, 100000, 15602, 100000, 15602 2 | 2.763275, 100000, 15230, 100000, 15230 3 | 2.698123, 100000, 14831, 100000, 14831 4 | 2.632971, 100000, 14298, 100000, 14298 5 | 2.567820, 100000, 13413, 100000, 13413 6 | 2.502668, 100000, 12944, 100000, 12944 7 | 2.437516, 100000, 12470, 100000, 12470 8 | 2.372364, 100000, 11617, 100000, 11617 9 | 2.307212, 100000, 10782, 100000, 10782 10 | 2.242060, 100000, 10394, 100000, 10394 11 | 2.176908, 100000, 9644, 100000, 9644 12 | 2.111756, 100000, 9005, 100000, 9005 13 | 2.046605, 100000, 8457, 100000, 8457 14 | 1.981453, 100000, 7723, 100000, 7723 15 | 1.916301, 100000, 7177, 100000, 7177 16 | 1.851149, 100000, 6322, 100000, 6322 17 | 1.785997, 100000, 5641, 100000, 5641 18 | 1.720845, 100000, 4887, 100000, 4887 19 | 1.655693, 100000, 4438, 100000, 4438 20 | 1.590541, 100000, 3762, 100000, 3762 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_2.txt: -------------------------------------------------------------------------------- 1 | 2.000000, 200000, 28465, 100000, 19893 2 | 1.953931, 200000, 27476, 100000, 19136 3 | 1.907861, 200000, 26120, 100000, 18165 4 | 1.861792, 200000, 24725, 100000, 17205 5 | 1.815723, 200000, 23517, 100000, 16294 6 | 1.769653, 200000, 21885, 100000, 15190 7 | 1.723584, 200000, 20840, 100000, 14447 8 | 1.677515, 200000, 19281, 100000, 13283 9 | 1.631445, 200000, 17880, 100000, 12343 10 | 1.585376, 200000, 16527, 100000, 11391 11 | 1.539307, 200000, 15129, 100000, 10415 12 | 1.493237, 200000, 13733, 100000, 9418 13 | 1.447168, 200000, 12282, 100000, 8411 14 | 1.401099, 200000, 11020, 100000, 7537 15 | 1.355029, 200000, 9708, 100000, 6631 16 | 1.308960, 200000, 8601, 100000, 5822 17 | 1.262891, 200000, 7229, 100000, 4880 18 | 1.216821, 200000, 6143, 100000, 4138 19 | 1.170752, 200000, 5251, 100000, 3576 20 | 1.124683, 200000, 4290, 100000, 2881 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_3.txt: -------------------------------------------------------------------------------- 1 | 1.632993, 300000, 36211, 100000, 20164 2 | 1.595378, 300000, 34244, 100000, 19105 3 | 1.557762, 300000, 32168, 100000, 17902 4 | 1.520147, 300000, 29791, 100000, 16647 5 | 1.482531, 300000, 27436, 100000, 15292 6 | 1.444916, 300000, 25377, 100000, 14188 7 | 1.407300, 300000, 23377, 100000, 13064 8 | 1.369685, 300000, 21153, 100000, 11751 9 | 1.332070, 300000, 18959, 100000, 10565 10 | 1.294454, 300000, 17027, 100000, 9406 11 | 1.256839, 300000, 14850, 100000, 8343 12 | 1.219223, 300000, 13124, 100000, 7316 13 | 1.181608, 300000, 11207, 100000, 6243 14 | 1.143992, 300000, 9759, 100000, 5452 15 | 1.106377, 300000, 7741, 100000, 4312 16 | 1.068761, 300000, 6428, 100000, 3614 17 | 1.031146, 300000, 5167, 100000, 2916 18 | 0.993530, 300000, 4178, 100000, 2364 19 | 0.955915, 300000, 3218, 100000, 1823 20 | 0.918300, 300000, 2435, 100000, 1381 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_4.txt: -------------------------------------------------------------------------------- 1 | 1.414214, 400000, 44002, 100000, 21508 2 | 1.381638, 400000, 40763, 100000, 19883 3 | 1.349062, 400000, 37500, 100000, 18328 4 | 1.316486, 400000, 34402, 100000, 16994 5 | 1.283910, 400000, 30930, 100000, 15275 6 | 1.251334, 400000, 28548, 100000, 14144 7 | 1.218758, 400000, 25689, 100000, 12725 8 | 1.186182, 400000, 23126, 100000, 11469 9 | 1.153606, 400000, 20031, 100000, 9969 10 | 1.121030, 400000, 17883, 100000, 8887 11 | 1.088454, 400000, 14959, 100000, 7546 12 | 1.055878, 400000, 12759, 100000, 6481 13 | 1.023302, 400000, 10772, 100000, 5462 14 | 0.990726, 400000, 8812, 100000, 4463 15 | 0.958150, 400000, 7186, 100000, 3647 16 | 0.925574, 400000, 5754, 100000, 2952 17 | 0.892999, 400000, 4251, 100000, 2242 18 | 0.860423, 400000, 3369, 100000, 1756 19 | 0.827847, 400000, 2375, 100000, 1283 20 | 0.795271, 400000, 1685, 100000, 926 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_5.txt: -------------------------------------------------------------------------------- 1 | 1.264911, 500000, 59237, 100000, 22729 2 | 1.235774, 500000, 54438, 100000, 20893 3 | 1.206637, 500000, 50574, 100000, 19374 4 | 1.177501, 500000, 46021, 100000, 17771 5 | 1.148364, 500000, 41948, 100000, 16080 6 | 1.119227, 500000, 37194, 100000, 14326 7 | 1.090090, 500000, 33784, 100000, 13047 8 | 1.060953, 500000, 29614, 100000, 11364 9 | 1.031817, 500000, 25992, 100000, 9988 10 | 1.002680, 500000, 22299, 100000, 8487 11 | 0.973543, 500000, 19170, 100000, 7363 12 | 0.944406, 500000, 15939, 100000, 6169 13 | 0.915269, 500000, 13310, 100000, 5101 14 | 0.886133, 500000, 10954, 100000, 4197 15 | 0.856996, 500000, 8759, 100000, 3359 16 | 0.827859, 500000, 6990, 100000, 2675 17 | 0.798722, 500000, 5218, 100000, 1992 18 | 0.769585, 500000, 3976, 100000, 1517 19 | 0.740449, 500000, 3035, 100000, 1150 20 | 0.711312, 500000, 2123, 100000, 800 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_6.txt: -------------------------------------------------------------------------------- 1 | 1.154701, 600000, 75397, 100000, 24931 2 | 1.128102, 600000, 69136, 100000, 22821 3 | 1.101504, 600000, 64161, 100000, 21106 4 | 1.074906, 600000, 58082, 100000, 19224 5 | 1.048308, 600000, 53702, 100000, 17672 6 | 1.021710, 600000, 47753, 100000, 15745 7 | 0.995112, 600000, 42634, 100000, 14066 8 | 0.968514, 600000, 37452, 100000, 12342 9 | 0.941915, 600000, 33315, 100000, 10954 10 | 0.915317, 600000, 28457, 100000, 9281 11 | 0.888719, 600000, 24573, 100000, 7992 12 | 0.862121, 600000, 20633, 100000, 6741 13 | 0.835523, 600000, 16907, 100000, 5501 14 | 0.808925, 600000, 14298, 100000, 4668 15 | 0.782327, 600000, 11365, 100000, 3684 16 | 0.755728, 600000, 9090, 100000, 2934 17 | 0.729130, 600000, 7134, 100000, 2287 18 | 0.702532, 600000, 5539, 100000, 1745 19 | 0.675934, 600000, 4173, 100000, 1348 20 | 0.649336, 600000, 3054, 100000, 951 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_7.txt: -------------------------------------------------------------------------------- 1 | 1.069045, 700000, 95864, 100000, 27144 2 | 1.044420, 700000, 86696, 100000, 24638 3 | 1.019795, 700000, 80540, 100000, 22888 4 | 0.995170, 700000, 74057, 100000, 21017 5 | 0.970545, 700000, 67267, 100000, 19048 6 | 0.945919, 700000, 60113, 100000, 16953 7 | 0.921294, 700000, 53056, 100000, 15004 8 | 0.896669, 700000, 46704, 100000, 13325 9 | 0.872044, 700000, 40739, 100000, 11608 10 | 0.847419, 700000, 34925, 100000, 9824 11 | 0.822794, 700000, 30122, 100000, 8552 12 | 0.798169, 700000, 25623, 100000, 7251 13 | 0.773544, 700000, 20852, 100000, 5880 14 | 0.748919, 700000, 16950, 100000, 4781 15 | 0.724294, 700000, 13961, 100000, 3914 16 | 0.699669, 700000, 10970, 100000, 3091 17 | 0.675043, 700000, 8787, 100000, 2433 18 | 0.650418, 700000, 6637, 100000, 1839 19 | 0.625793, 700000, 5206, 100000, 1446 20 | 0.601168, 700000, 3896, 100000, 1076 21 | -------------------------------------------------------------------------------- /notebooks/map/random/results_random_map_16_8.txt: -------------------------------------------------------------------------------- 1 | 1.000000, 800000, 113789, 100000, 28448 2 | 0.976965, 800000, 105305, 100000, 26381 3 | 0.953931, 800000, 96449, 100000, 24124 4 | 0.930896, 800000, 86232, 100000, 21522 5 | 0.907861, 800000, 78542, 100000, 19560 6 | 0.884827, 800000, 69385, 100000, 17374 7 | 0.861792, 800000, 61136, 100000, 15258 8 | 0.838757, 800000, 53669, 100000, 13472 9 | 0.815723, 800000, 46114, 100000, 11506 10 | 0.792688, 800000, 39719, 100000, 9804 11 | 0.769653, 800000, 32080, 100000, 8046 12 | 0.746619, 800000, 26870, 100000, 6682 13 | 0.723584, 800000, 21208, 100000, 5284 14 | 0.700549, 800000, 16013, 100000, 4029 15 | 0.677515, 800000, 13027, 100000, 3259 16 | 0.654480, 800000, 10188, 100000, 2545 17 | 0.631445, 800000, 7221, 100000, 1795 18 | 0.608411, 800000, 4972, 100000, 1240 19 | 0.585376, 800000, 3538, 100000, 881 20 | 0.562341, 800000, 2247, 100000, 554 21 | --------------------------------------------------------------------------------