{ "cells": [ { "cell_type": "markdown", "id": "7b5fd8d3", "metadata": {}, "source": [ "# Evaluating the Trained Channel Estimator\n", "Now that we have a trained model, we can use it in the communication pipeline and compare its performance with baselines. In this case we compare it with perfect channel estimation and **NeoRadium**'s Least-Square channel estimation method.\n", "\n", "The following diagram shows the pipeline used for evaluation of our deep-learning-based channel estimator.\n", "\n", "![Evaluation-Pipeline](EvalPipeline.png)\n", "\n", "So, lets get started by importing the required modules." ] }, { "cell_type": "code", "execution_count": 1, "id": "2415601e", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import scipy.io\n", "import time\n", "import matplotlib.pyplot as plt\n", "\n", "from neoradium import Carrier, PDSCH, CdlChannel, AntennaPanel, Grid, random\n", "\n", "import torch\n", "from torch import nn" ] }, { "cell_type": "markdown", "id": "ebe23527", "metadata": {}, "source": [ "## Load the trained mode\n", "Here we define the channel estimator model and initialize it with the trained parameters." ] }, { "cell_type": "code", "execution_count": 2, "id": "8c2ba366", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using 'Metal' device.\n" ] } ], "source": [ "# ResNet Block\n", "class ResBlock(nn.Module):\n", " def __init__(self, inDepth, midDepth, outDepth, kernel=(3,3), stride=(1,1)):\n", " super().__init__()\n", " if isinstance(stride, int): stride = (stride, stride)\n", " if isinstance(kernel, int): kernel = (kernel, kernel)\n", " \n", " self.conv1 = nn.Conv2d(inDepth, midDepth, 1, stride, padding='valid') # 1x1 conv.\n", " self.bn1 = nn.BatchNorm2d(midDepth)\n", " self.conv2 = nn.Conv2d(midDepth, midDepth, kernel, padding='same')\n", " self.bn2 = nn.BatchNorm2d(midDepth)\n", " self.conv3 = nn.Conv2d(midDepth, outDepth, 1, stride, padding='valid') # 1x1 conv.\n", " self.bn3 = nn.BatchNorm2d(outDepth)\n", " self.relu = nn.ReLU(inplace=True)\n", " \n", " self.downSampleNet = None\n", " if ((stride != (1,1)) or (inDepth!=outDepth)):\n", " self.downSampleNet = nn.Sequential(nn.Conv2d(inDepth, outDepth, 1, stride), # 1x1 conv.\n", " nn.BatchNorm2d(outDepth) )\n", "\n", " for bn in [self.bn1, self.bn2, self.bn3]:\n", " nn.init.ones_(bn.weight)\n", " nn.init.zeros_(bn.bias)\n", " \n", " for conv in [self.conv1, self.conv2, self.conv3]:\n", " nn.init.trunc_normal_(conv.weight, std=1/np.sqrt(np.prod(list(conv.weight.shape)[1:]))) \n", " nn.init.zeros_(conv.bias)\n", " \n", " nn.init.zeros_(self.bn3.weight) # This could improve results. It makes the block start like identity.\n", " \n", " def forward(self, x):\n", " out = self.conv1(x)\n", " out = self.bn1(out)\n", " out = self.relu(out)\n", " \n", " out = self.conv2(out)\n", " out = self.bn2(out)\n", " out = self.relu(out)\n", " \n", " out = self.conv3(out)\n", " out = self.bn3(out)\n", " \n", " if self.downSampleNet is None: out += x\n", " else: out += self.downSampleNet(x)\n", " out = self.relu(out)\n", " \n", " return out\n", " \n", "# The Channel Estimator model\n", "class ChEstNet(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.res1 = ResBlock(2, 16, 64, (9,11)) # Res Block 9x11 kernel\n", " self.res2 = ResBlock(64, 16, 64, (3,7)) # Res Block 3x7 kernel\n", " self.res3 = ResBlock(64, 16, 64, (3,7)) # Res Block 3x7 kernel\n", " \n", " self.conv = nn.Conv2d(64, 2, 3, padding='same')\n", " nn.init.trunc_normal_(self.conv.weight, std=1/np.sqrt(np.prod(list(self.conv.weight.shape)[1:]))) \n", " nn.init.zeros_(self.conv.bias)\n", "\n", " def forward(self, x):\n", " out = self.res1(x)\n", " out = self.res2(out)\n", " out = self.res3(out)\n", " out = self.conv(out)\n", " return out\n", " \n", "# Checking GPU availability\n", "device = \"cuda\" if torch.cuda.is_available() else \"mps\" if torch.backends.mps.is_available() else \"cpu\"\n", "print(\"Using '%s' device.\"%({'cuda':'Cuda', 'mps':'Metal','cpu':'CPU'}[device]))\n", "\n", "# Instantiate the model and move it to the target device\n", "model = ChEstNet().to(device)\n", "\n", "# Load the trained model parameters:\n", "# Note: The model file \"ChEstModel-300.pth\" was trained with 300 epochs using a parameter search. It performs\n", "# better than the model trained in the previous step with 100 epochs. You can try both by choosing the \n", "# corresponding line below.\n", "model.load_state_dict(torch.load('Models/ChEstModelWeights.pth', map_location=device, weights_only=True)); # From prev. step.\n", "# model.load_state_dict(torch.load('Models/ChEstModel-300.pth', map_location=device, weights_only=True)); # Trained for 300 Epochs\n", "model.eval(); # Set the model to evaluation mode\n" ] }, { "cell_type": "markdown", "id": "1ecab548", "metadata": {}, "source": [ "## ``mlChanEst`` function\n", "The ``mlChanEst`` function in the following cell receives the DMRS information, the received resource grid, and the trained model as input. It first calculates the channel estimates at the pilot locations using LS method and then converts these estimates to a set of ``L x K`` complex matrixes that are fed to the model for inference. (``L`` is the number of OFDM symbols per slot and ``K`` is the number of subcarriers) \n", "\n", "The model outputs another set of ``L x K`` matrixes which contain the predicted channel information. These matrixes are then re-packaged as a 4-D complex numpy array that is returned as the estimated channel." ] }, { "cell_type": "code", "execution_count": 3, "id": "a56e6fd7", "metadata": {}, "outputs": [], "source": [ "def mlChanEst(dmrs, rxGrid, model):\n", " rsGrid = rxGrid.bwp.createGrid( len(dmrs.pxxch.portSet) ) # Create an empty resource grid\n", " dmrs.populateGrid(rsGrid) # Populate the grid with DMRS values\n", " rsIndexes = rsGrid.getReIndexes(\"DMRS\") # This contains the locations of DMRS values\n", " \n", " rr, ll, kk = rxGrid.shape # Number of RX antenna, Number of symbols, Number of subcarriers\n", " pp, ll2, kk2 = rsGrid.shape # Number of Ports (From DMRS)\n", " if (ll!=ll2) or (kk!=kk2): raise ValueError(\"The Gird size (%dx%d) does not match the DMRs (%dx%d).\"%(ll,kk,ll2,kk2))\n", "\n", " modelIn = []\n", " for p in range(pp): # For each DMRS port (i.e. each layer)\n", " portLs = rsIndexes[1][(rsIndexes[0]==p)] # Indexes of symbols containing pilots in this port\n", " portKs = rsIndexes[2][(rsIndexes[0]==p)] # Indexes of subcarriers containing pilots in this port\n", "\n", " ls = np.unique(portLs) # Unique Indexes of symbols containing pilots in this port\n", " ks = portKs[portLs==ls[0]] # Unique Indexes of subcarriers containing pilots in this port\n", " numLs, numKs = len(ls), len(ks) # Number of OFDM symbols and number of subcarriers\n", "\n", " pilotValues = rsGrid[p,ls,:][:,ks] # Pilot values in this port\n", " rxValues = rxGrid.grid[:,ls,:][:,:,ks] # Received values for pilot signals\n", " hEst = np.transpose(rxValues/pilotValues[None,:,:], (1,2,0)) # Channel estimates at pilot locations (L,K,Nr)\n", " for r in range(rr): # For each receiver antenna\n", " inH = np.zeros((2,)+rxGrid.shape[1:], dtype=np.float64) # Create one 3D matrix with all zeros\n", " for li,l in enumerate(ls):\n", " inH[0,l,ks] = hEst[li,:,r].real # Set the LS estimates at pilot location (Real)\n", " inH[1,l,ks] = hEst[li,:,r].imag # Set the LS estimates at pilot location (Imaginary)\n", " modelIn += [ inH ]\n", "\n", " # Package all inputs as a batch in a PyTorch tensor\n", " modelIn = torch.from_numpy( np.float32(np.stack(modelIn)) ).to(device) \n", " with torch.no_grad(): modelOut = model(modelIn) # Run inference for the whole batch\n", " modelOut = modelOut.cpu().numpy() # Bring the results back to CPU and convert to numpy\n", " estChan = np.transpose( modelOut.reshape((pp,rr)+modelOut.shape[1:]), (3,4,1,0,2) ) # Convert to a 5-D tensor\n", " estChan = estChan[...,0] + 1j*estChan[...,1] # Convert to a 4-D complex tensor\n", " return estChan\n" ] }, { "cell_type": "markdown", "id": "35d7033d", "metadata": {}, "source": [ "## Evaluation Pipeline\n", "The following cell implements the evaluation pipeline as shown above. It runs the pipeline 3 times with perfect, ML, and LS channel estimation methods and prints the results at the end. As it can be seen, the ML-based channel estimation performs better than LS method which is based on interpolation." ] }, { "cell_type": "code", "execution_count": 4, "id": "64a5cf3a", "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Simulating end-to-end for \"16QAM\", with \"Perfect\" channel estimation, in time domain.\n", "SNR(dB) Total Bits Bit Errors BER(%) time(Sec.)\n", "------- ---------- ---------- ------ ----------\n", " 5 2545920 1036799 40.72 5.68\n", " 10 2545920 850716 33.41 5.74\n", " 15 2545920 606267 23.81 5.72\n", " 20 2545920 350625 13.77 5.80\n", " 25 2545920 145817 5.73 5.75\n", "\n", "Simulating end-to-end for \"16QAM\", with \"ML\" channel estimation, in time domain.\n", "SNR(dB) Total Bits Bit Errors BER(%) time(Sec.)\n", "------- ---------- ---------- ------ ----------\n", " 5 2545920 1083427 42.56 7.34\n", " 10 2545920 887882 34.87 6.49\n", " 15 2545920 637612 25.04 6.28\n", " 20 2545920 389796 15.31 6.18\n", " 25 2545920 197993 7.78 6.21\n", "\n", "Simulating end-to-end for \"16QAM\", with \"LS\" channel estimation, in time domain.\n", "SNR(dB) Total Bits Bit Errors BER(%) time(Sec.)\n", "------- ---------- ---------- ------ ----------\n", " 5 2545920 1138786 44.73 5.85\n", " 10 2545920 968019 38.02 5.90\n", " 15 2545920 717426 28.18 5.93\n", " 20 2545920 448406 17.61 5.91\n", " 25 2545920 217902 8.56 6.01\n" ] }, { "data": { "image/png": "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3bvH1KlT059nv379qFatGgMGDABIfy8807lzZ4oXL863337LqVOnmD9/Po6Ojnz//ffpx/Tr149FixbRsWNHPvroI44dO8a3337LpUuXWLt2bfpxX375JRMmTKB58+Y0b96cU6dO0bhx45cui40bN45vv/02Pbbo6GhOnDjBqVOnaNSo0Stfr9DQUGrWrEl8fDwjRozA3t6eRYsW0bp1a1atWkW7du2oW7cuixcv5v3336dRo0bpr9mrbNiwAYD333//Tacr3ZveE8/88ssvtG7dmh49epCcnMzy5cvp1KkTGzdupEWLFhnaPHjwIGvWrGHIkCFYWlry66+/0qFDB27fvo29vX2GY7NyziZOnMgXX3xB586d6devH+Hh4UybNo26deu+9FnPzvPO7O+2qalp+kjvoEGDWLVqFcOGDaNs2bJERkZy8OBBLl26ROXKlfn888+Jiori7t276e/TNxXvp6Wl0axZM+rWrcsPP/zA0qVLGTZsGObm5nz++ef06NGD9u3bM3v2bHr16kWNGjUoXrw4ADdu3GDdunV06tSJ4sWLExoaypw5c6hXrx4XL17E2dmZMmXK8PXXX/Pll18yYMAA6tSpA0DNmjUzjSern79nsnNuc00v6Zl4o1d9gzM2Nn5pJEdRMo5IKYruWxdvGIV60atGYgClSZMmL8VVu3btl77pPftWM3v27Az7f/75ZwVQlixZkr4vOTlZqVGjhmJhYaFER0crivL8m4+VlZUSFhaWpbjd3NyUxo0bK+Hh4Up4eLhy7tw55f3330//xvGiF0eenvn2228VlUql3Lp1K33f0KFDM/22fODAAQV46dvV1q1bM93/T5mNMiYnJyuOjo5K+fLllYSEhPT9GzduVADlyy+/TN/37Bx99tlnr+3nmbZt2yomJiYZntvFixcVjUbz2hEpRck4OviiZ98S//kNvkGDBkqFChUyjIZotVqlZs2aSqlSpV56Df75/omJiVFsbGxeGoF4+PChYm1tnWH/s9fh66+/znCsj4+P4uvrm/5zeHj4G0ehXvQstiZNmmT4BlujRg1FpVIpgwYNSt+XmpqquLq6ZhiRW7dunQIoEyZMyNBux44dFZVKpVy7di19n7m5eYbX+5lnoxt9+/bNsL9du3aKvb19+s9BQUEKoPTr1y/DcWPGjFEAZffu3YqiKEpYWJhiZGSktGjR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3SeSDE50PcOL1O+//860adOoUaMGK1euZPDgwTz//PM3fXUpMDCQtWvX8tNPP9GjRw9atWpFZGQk06ZNczjDuXPnyMnJwd/f/5rt/v7+nD59GgCLxcL777/PQw89RMOGDXnhhRfw8/O74byoqCgSEhLYunWrw5lEREQEhrWuwUM1y5GRbWXQ/DgupmQaHekaFqMDWK1WGjduzIQJEwAICwtj9+7dTJ8+nd69e9/wZypXrsy8efNo0aIFVatW5V//+hcmk8npWR977DEee+wxpx9HREREcpnNJj7sFkbHT37i2IVUnv9iB3P63ouL2fl/9/PC8FekKlSoQGho6DXbateuzbFjx276M4mJiQwYMICOHTuSmprKiBEj8pWhbNmyuLi4XHeyemJiIgEBAfmaLSIiIvnj6+XKjGfC8XA18+OBc0xevd/oSFcZXqSaNWvGvn37rtm2f/9+goODb7j/uXPnaN26NbVr12bJkiXExsayaNEiXnzxRYczuLm5ER4eTmxs7NVtVquV2NhYmjZt6vBcERERKRi1K5Tk7S71Afhk3UFW/Xba4ES5DC9SI0aMYMuWLUyYMIGDBw+ycOFC/vnPfxIVFXXdvlarlfbt2xMcHMyiRYuwWCyEhoayevVqZs+ezeTJk294jCtXrhAfH098fDwAhw8fJj4+/ppXvaKjo5k5cyZz585lz549DB48mJSUFPr27euU31tERETs0zksiD73VwHghS9/5fC5FGMDUQTOkWrSpAlLly5l1KhRvP7664SEhPDhhx/Ss2fP6/Y1m81MmDCBBx98EDc3t6vbGzRowJo1ayhXrtwNj7Ft2zYeeuihq4+jo6MB6N27N3PmzAGgW7dunD17lrFjx3L69GkaNmzI999/f90J6CIiImKcVzrUZveJJLYdvUjU5/H0r2JsHsOLFMCjjz7Ko48+mqd927Rpc8PtYWFhN/2Zli1b5uku0kOHDmXo0KF5yiEiIiKFz81iZmrPRjzy8U8cOJPC5zlmOufhb7yzGP7WnoiIiIg9ypf0YGrPRljMJrwskGNVkRIRERHJsyZVyrB86P08VdWKxcW4OqMiJSIiIsVStXIljI6gIiUiIiLiKBUpEREREQepSImIiIg4SEVKRERExEEqUiIiIiIOUpESERERcZCKlIiIiIiDVKREREREHKQiJSIiIuIgFSkRERERB6lI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Pzd8+HBatmx59fFrr72GyWTCZDLh4uJCpUqVGDBgABcuXCjMX0dECoHutSci8qeuXbuSmZnJ3LlzqVq1KomJicTGxnL+/Pmr+3h4eDBy5Eg2bNhwy1l16tRhzZo15OTksGfPHv7+97+TlJTEokWLnP1riEghUpESEQEuXbrEjz/+yPr162nRogUAwcHB3HvvvdfsN2DAAKZPn86KFSvo0KHDTedZLBYCAgIACAoK4sknn2T27NnO+wVExBB6a09EBPD29sbb25tly5aRkZFx0/1CQkIYNGgQo0aNwmq15mn2kSNHWLlyJW5ubgUVV0SKCBUpERFyX0GaM2cOc+fOpVSpUjRr1oxXXnmFnTt3Xrfvq6++yuHDh1mwYMFN5+3atQtvb288PT0JCQnht99+Y+TIkc78FUTEACpSIiJ/6tq1KydPnuSbb77h4YcfZv369TRq1Ig5c+Zcs1+5cuV48cUXGTt2LJmZmTecVbNmTeLj49m6dSsjR46kXbt2PPfcc4XwW4hIYVKREhH5Lx4eHrRp04YxY8awadMm+vTpw7hx467bLzo6mrS0NKZOnXrDOW5ublSvXp26devy9ttv4+Liwvjx450dX0QKmYqUiMgthIaGkpKSct12b29vxowZw1tvvcXly5dvO+fVV1/lvffe4+TJk86IKSIGUZESEQHOnz9Pq1atmD9/Pjt37uTw4cN89dVXTJo0iU6dOt3wZwYMGICvry8LFy687fymTZtSv359JkyYUNDRRcRAKlIiIuS+whQREcHkyZNp3rw5devWZcyYMfTv359PPvnkhj/j6urKG2+8QXp6ep6OMWLECGbNmsUff/xRkNFFxEAmm81mMzqEiIiISHGkV6REREREHKQiJSIiIuIgFSkRERERB6lIiYiIiDhIRUpERETEQSpSIiIiIg5SkRIRERFxkIqUiIiIiINUpEREREQcpCIlIiIi4iAVKREREREHqUiJiIiIOOj/AL/qeGC3tlmbAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "numFrames = 2 # Number of time-domain frames\n", "snrDbs = [5,10,15,20,25] # SNR values (in dB) for which we want to evaluate the model\n", "freqDomain = False # Set to True to apply channel in frequency domain\n", "\n", "carrier = Carrier(numRbs=51, spacing=30) # Create a carrier with 51 RBs and 30KHz subcarrier spacing\n", "bwp = carrier.curBwp # The only bandwidth part in the carrier\n", "\n", "# Create a PDSCH object\n", "pdsch = PDSCH(bwp, interleavingBundleSize=0, numLayers=2, nID=carrier.cellId, modulation=\"16QAM\")\n", "pdsch.setDMRS(prgSize=0, configType=2, additionalPos=2) # Specify the DMRS configuration\n", "\n", "numSlots = bwp.slotsPerFrame*numFrames # Total number of slots\n", "results = {} # Dictionary to save the results\n", "\n", "for chanEstMethod in [\"Perfect\", \"ML\", \"LS\"]: # Three different channel estimation methods\n", " results[chanEstMethod] = {}\n", " print(\"\\nSimulating end-to-end for \\\"%s\\\", with \\\"%s\\\" channel estimation, in %s domain.\"%\n", " (\"16QAM\", chanEstMethod, \"frequency\" if freqDomain else \"time\"))\n", " print(\"SNR(dB) Total Bits Bit Errors BER(%) time(Sec.)\")\n", " print(\"------- ---------- ---------- ------ ----------\")\n", " for snrDb in snrDbs: # For each SNR value in snrDbs\n", " random.setSeed(123) # Making the results reproducible for each SNR\n", " t0 = time.time() # Start time for each SNR\n", " carrier.slotNo = 0\n", "\n", " # Creating a CdlChannel object\n", " channel = CdlChannel('C', delaySpread=300, carrierFreq=4e9, dopplerShift=5,\n", " txAntenna = AntennaPanel([2,2], polarization=\"x\"), # 8 TX antenna\n", " rxAntenna = AntennaPanel([1,1], polarization=\"+\"), # 2 RX antenna\n", " seed = 123,\n", " timing = \"nearest\") \n", "\n", " bitErrors = 0\n", " totalBits = 0\n", "\n", " for slotNo in range(numSlots):\n", " grid = pdsch.getGrid() # Create a resource grid populated with DMRS\n", " numBits = pdsch.getBitSizes(grid)[0] # Number of bits available in the resource grid\n", " txBits = random.bits(numBits) # Create random binary data\n", "\n", " pdsch.populateGrid(grid, txBits) # Map/modulate the data to the resource grid\n", "\n", " # Store the indexes of the PDSCH data in pdschIndexes to be used later.\n", " pdschIndexes = pdsch.getReIndexes(grid, \"PDSCH\") \n", "\n", " # Getting the Precoding Matrix, and precoding the resource grid\n", " channelMatrix = channel.getChannelMatrix(bwp) # Get the channel matrix\n", " precoder = pdsch.getPrecodingMatrix(channelMatrix) # Get the precoder matrix from PDSCH object\n", " precodedGrid = grid.precode(precoder) # Perform the precoding\n", "\n", " if freqDomain:\n", " rxGrid = precodedGrid.applyChannel(channelMatrix) # Apply the channel in frequency domain\n", " rxGrid = rxGrid.addNoise(snrDb=snrDb) # Add noise\n", " else:\n", " txWaveform = precodedGrid.ofdmModulate() # OFDM Modulation\n", " maxDelay = channel.getMaxDelay() # Get the max. channel delay\n", " txWaveform = txWaveform.pad(maxDelay) # Pad with zeros\n", " rxWaveform = channel.applyToSignal(txWaveform) # Apply channel in time domain\n", " noisyRxWaveform = rxWaveform.addNoise(snrDb=snrDb, nFFT=bwp.nFFT) # Add noise\n", " offset = channel.getTimingOffset() # Get timing info for synchronization\n", " syncedWaveform = noisyRxWaveform.sync(offset) # Synchronization\n", " rxGrid = syncedWaveform.ofdmDemodulate(bwp) # OFDM demodulation\n", " \n", " if chanEstMethod == \"Perfect\": # Perfect Channel Estimation\n", " estChannelMatrix = channelMatrix @ precoder[None,...]\n", " elif chanEstMethod == \"LS\": # LS + Interpolation Channel Estimation\n", " estChannelMatrix, noiseEst = rxGrid.estimateChannelLS(pdsch.dmrs, polarInt=False, \n", " kernel='linear')\n", " elif chanEstMethod == \"ML\": # ML-Based Channel Estimation\n", " estChannelMatrix = mlChanEst(pdsch.dmrs, rxGrid, model)\n", " else: assert(0)\n", "\n", " eqGrid, llrScales = rxGrid.equalize(estChannelMatrix) # Equalization\n", "\n", " rxBits = pdsch.getHardBitsFromGrid(eqGrid, pdschIndexes)[0] # Demodulation\n", " bitErrors += np.abs(rxBits-txBits).sum() # Calculating number of bit errors\n", " totalBits += numBits\n", " print(\"\\r %3d %8d %8d %6.2f %6.2f\"%(snrDb, totalBits, bitErrors, \n", " bitErrors*100/totalBits,time.time()-t0),end='')\n", "\n", " carrier.goNext() # Prepare the carrier object for the next slot\n", " channel.goNext() # Prepare the channel model for the next slot\n", "\n", " dt = time.time()-t0 # Total time for this SNR\n", " results[chanEstMethod][snrDb] = {\"totalBits\":totalBits, \n", " \"bitErrors\":bitErrors, \n", " \"BER\": bitErrors*100/totalBits,\n", " \"Time\": dt}\n", " print(\"\\r %3d %8d %8d %6.2f %6.2f\"%(snrDb, totalBits, bitErrors, \n", " bitErrors*100/totalBits, dt))\n", " \n", "# Compare the results in a plot:\n", "for i,chanEstMethod in enumerate(['Perfect', 'ML', 'LS']):\n", " bers = [results[chanEstMethod][snrDb][\"BER\"] for snrDb in snrDbs]\n", " plt.plot(snrDbs, bers, label=chanEstMethod)\n", "plt.legend()\n", "plt.title(\"Bit Error Rate for different mothods of Channel Estimation.\");\n", "plt.grid()\n", "plt.xlabel(\"SNR\")\n", "plt.xticks(snrDbs)\n", "plt.ylabel(\"BER (%)\")\n", "plt.yscale('log')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "c0e14764", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.6" } }, "nbformat": 4, "nbformat_minor": 5 }