Comparing SISO CDL Channel results with Matlab
Compare the results of this notebook with the Matlab file SisoCdl.mlx in the MatlabFiles directory.
The “.mat” files in the MatlabFiles directory were created by Matlab running the SisoCdl.mlx file. If you want to recreate these files, follow the instructions in the Matlab file. Here is the execution results of this code in Matlab.
[1]:
import numpy as np
import scipy.io
from neoradium import Carrier, CdlChannel, random, Waveform
from neoradium.utils import getNmse
matlabFilesPath = "./MatlabFiles"
[2]:
carrier = Carrier(startRb=0, numRbs=25, spacing=15)    # Carrier 25 Resource Blocks, 15KHz subcarrier spacing
bwp = carrier.curBwp                                   # The only bandwidth part in the carrier
cdlModel = 'C'
seed = 123
phiInit, coupling = CdlChannel.getMatlabRandomInit(cdlModel, seed) # Match Matlab random values
speedKmh = 15                # speed of UE device: 15 km/h
speed = speedKmh*1000/3600   # m/s
c = 299792458                # Speed of light
fc = 4e9                     # 4 GHz
d = speed*fc/c               # Doppler Shift (Hz)
# NOTE: Always make sure to use this antenna config in Matlab to match the standard and NeoRadium's default
# cdl.TransmitAntennaArray.Size = [1 1 1 1 1];     % 1x1 antenna panel
# cdl.TransmitAntennaArray.Element = '38.901';     % Make sure we are using 3GPP antennas. (Default is not 3GPP)
# cdl.TransmitArrayOrientation = [0; 0; 0];        % Transmit antenna orientation bearing(α), downtilt(β), and slant(γ) angles in degrees
# cdl.TransmitAntennaArray.PolarizationAngles = [0 90];
# cdl.ReceiveAntennaArray.Size = [1 1 1 1 1];     % 1x1 antenna
# cdl.ReceiveAntennaArray.Element = '38.901';     % Make sure we are using 3GPP antennas. (Default is not 3GPP)
# cdl.ReceiveArrayOrientation = [180; 0; 0];      % Receive antenna orientation bearing(α), downtilt(β), and slant(γ) angles in degrees
# cdl.ReceiveAntennaArray.PolarizationAngles = [0 90];
# Create the channel model
channel = CdlChannel(bwp, cdlModel, delaySpread=10, carrierFreq=fc, dopplerShift=d,
                     initialPhases = phiInit, rayCoupling = coupling,
                     stopBandAtten = 70)            # NeoRadium default is 80; Matlab default is 70;
channel.print()
CDL-C Channel Properties:
  carrierFreq:          4 GHz
  normalizeGains:       True
  normalizeOutput:      True
  txDir:                Downlink
  filterLen:            16 samples
  delayQuantSize:       64
  stopBandAtten:        70 dB
  dopplerShift:         55.59401586635868 Hz
  coherenceTime:        7.611 milliseconds
  delaySpread:          10 ns
  ueDirAZ:              0.0°, 90.0°
  Cross Pol. Power:     7 dB
  angleSpreads:         2° 15° 3° 7°
  TX Antenna:
    freqRange:                   0 Hz .. 100 GHz
    polAngle:                    0°
    polModel:                    2
    beamWidth:                   65°,65°
    verticalSidelobeAttenuation: 30
    maxAttenuation:              30 dB
    mainMaxGain:                 8 dBi
  RX Antenna:
    freqRange:                   0 Hz .. 100 GHz
    polAngle:                    0°
    polModel:                    2
    beamWidth:                   65°,65°
    verticalSidelobeAttenuation: 30
    maxAttenuation:              30 dB
    mainMaxGain:                 8 dBi
    Orientation (𝛼,𝛃,𝛄): 180° 0° 0°
  hasLOS:               False
  NLOS Paths (24):
    Delays (ns):        0.000 2.099 2.219 2.329 2.176 6.366 6.448 6.560 6.584 7.935 8.213 9.336
                        12.28 13.08 21.70 27.10 42.58 46.00 54.90 56.07 63.06 66.37 70.42 86.52
    Powers (dB):        -4.40 -1.20 -3.50 -5.20 -2.50 0.000 -2.20 -3.90 -7.40 -7.10 -10.7 -11.1
                        -5.10 -6.80 -8.70 -13.2 -13.9 -13.9 -15.8 -17.1 -16.0 -15.7 -21.6 -22.8
    AODs (Deg):         -47  -23  -23  -23  -41  0    0    0    73   -64  80   -97
                        -55  -64  -78  103  99   89   -102 92   93   107  119  -124
    AOAs (Deg):         -101 120  120  120  -128 170  170  170  55   66   -48  47
                        68   -69  82   31   -16  4    -14  10   6    1    -22  34
    ZODs (Deg):         97   99   99   99   101  99   99   99   105  95   106  94
                        104  104  93   104  95   93   92   107  93   93   105  108
    ZOAs (Deg):         88   72   72   72   70   75   75   75   67   64   71   60
                        91   60   61   101  62   67   53   62   52   62   58   57
[3]:
# Create a random signal for 1 subframe (1 ms)
t = 0.001       # 1 subframe = 1 ms
numInputSamples = int(channel.sampleRate * t)
nr, nt = channel.nrNt     # Get the number of antanna from the channel
# Load the "txWaveform" generated by the Matlab code
txWaveform = scipy.io.loadmat(matlabFilesPath+'/txWaveform.mat')['txWaveform'].T
assert txWaveform.shape==(nt, numInputSamples)
# Check the following numbers with the Matlabmatlab-generated numbers to make sure we are using
# the same input signal:
print("TX Waveform Data:\n", np.round(txWaveform[0,200:204],4))  # Matlab: txWaveform(201:204,3:4)
# Use the following line instead of above line to create a random signal (The result will be
# different from Matlab)
# txWaveform = np.random.normal(size=(numSamples, nt)) + 1j*np.random.normal(size=(numSamples, nt))
# Now apply the channel to the waveform
rxWaveform = channel.applyToSignal(txWaveform)
print("RX Waveform Data:\n", np.round(rxWaveform[0,200:204],4))  # Matlab: rxWaveform(201:204,2)
# Load Matlab results and compare with the above results
rxWaveformMatlab = scipy.io.loadmat(matlabFilesPath+'/rxWaveform.mat')['rxWaveform']
assert rxWaveformMatlab.shape==(numInputSamples, nr)
print("NMSE:", getNmse(rxWaveformMatlab.T,rxWaveform.waveform))   # NMSE between NeoRadium and Matlab results
TX Waveform Data:
 [ 0.3957+0.3554j  0.1609-1.6695j -0.1543+0.4127j -0.484 -1.0458j]
RX Waveform Data:
 [ 1.0979-0.9033j  0.1692-0.5916j -0.7662-0.9718j  0.1534-0.7265j]
NMSE: 9.313019773677275e-05
[ ]: