Comparing the CDL Channel results with MATLAB

Compare the results of this notebook with the MATLAB file CDLTest.mlx in the MatlabFiles directory.

The “.mat” files in the MatlabFiles directory were created by MATLAB running the CDLTest.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, AntennaPanel, random, Waveform
from neoradium.utils import getNmse

matlabFilesPath = "./MatlabFiles"

CDL Channel Model

Now we want to create a CDL Channel object (CdlChannel) and apply it to the time-domain waveform.

Note 1: Since CDL is a statistical model, there is inherent randomness in how the phases are initialized and how rays are coupled. The
getMatlabRandomInit helper function can be used to create the same random initial phases and ray couplings that are generated by the MATLAB code.
Note 2: NeoRadium’s implementation of FIR filters used by the CDL channel is slightly different from MATLAB’s. To compensate for this
difference, we need to modify the stopBandAtten parameter.
Note 3: MATLAB uses a different order for the antenna elements in a panel from NeoRadium and the 3GPP standard. To compare the results, we set
the matlabOrder parameter to True for both antenna panels.
[2]:
carrier = Carrier(startRb=0, numRbs=25, spacing=15)    # Carrier 25 Resource Blocks, 15 kHz subcarrier spacing
bwp = carrier.curBwp                                   # The only bandwidth part in the carrier

cdlModel = 'D'
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)

# Create the channel model
channel = CdlChannel(bwp, cdlModel, delaySpread=10, carrierFreq=fc, dopplerShift=d,
                     initialPhases = phiInit, rayCoupling = coupling,
                     txAntenna = AntennaPanel([2,2], polarization="x", matlabOrder=True, polModel=2),
                     rxAntenna = AntennaPanel([1,1], polarization="+", matlabOrder=True, polModel=2),
                     txOrientation = [10, 20, 30],
                     rxOrientation = [180, 0, 0],
                     angleScaling = ([130,70,80,110], [5,11,3,3]),  # Angle Scaling
                     stopBandAtten = 70)                            # Default is 80
channel.print()

CDL-D Channel Properties:
  carrierFreq:              4 GHz
  normalizeGains:           True
  normalizeOutput:          True
  txDir:                    Downlink
  filterLen:                16 samples
  delayQuantSize:           64
  stopBandAtten:            70 dB
  dopplerShift:             55.59 Hz
  coherenceTime:            7.611 milliseconds
  delaySpread:              10 ns
  ueDirAZ:                  0°, 90°
  Angle Scaling:
    Means:                  130° 70° 80° 110°
    RMS Spreads:            5° 11° 3° 3°
  xPolPower:                11.00 dB
  angleSpreads:             5° 8° 3° 3°
  TX Antenna:
    Total Elements:         8
    spacing:                0.5𝜆, 0.5𝜆
    shape:                  2 rows x 2 columns
    polarization:           x
    Orientation (𝛼,𝛃,𝛄):     10° 20° 30°
  RX Antenna:
    Total Elements:         2
    spacing:                0.5𝜆, 0.5𝜆
    shape:                  1 rows x 1 columns
    polarization:           +
    Orientation (𝛼,𝛃,𝛄):     180° 0° 0°
  hasLOS:                   True
  LOS Path:
    Delay (ns):             0.00000
    Power (dB):             -0.20000
    AOD (Deg):              0.0
    AOA (Deg):              -180.0
    ZOD (Deg):              98.0
    ZOA (Deg):              82.0
  NLOS Paths (13):
    Delays (ns):            0.000 0.350 6.120 13.63 14.05 18.04 25.96 17.75 40.42 79.37 94.24 97.08 125.2
    Powers (dB):            -13.5 -18.8 -21.0 -22.8 -17.9 -20.1 -21.9 -22.9 -27.8 -23.6 -24.8 -30.0 -27.7
    AODs (Deg):             0    89   89   89   13   13   13   35   -64  -33  53   -132 77
    AOAs (Deg):             -180 89   89   89   163  163  163  -137 74   128  -120 -9   -84
    ZODs (Deg):             98   86   86   86   98   98   98   98   88   91   104  80   86
    ZOAs (Deg):             82   87   87   87   79   79   79   78   74   78   87   71   73

Applying the channel to a random waveform

Now we create a random waveform one subframe long (1 ms) and apply our CDL Channel to the waveform. To compare the results with MATLAB, we read the waveform from a file created by the MATLAB program CDLTest.mlx.

[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 antenna 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 MATLAB-generated numbers to make sure we are using
# the same input signal:
print("TX Waveform Data:\n", np.round(txWaveform[2:4,200:204].T,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[1,200:204].T,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:
 [[-1.4866-0.7976j  2.1968-0.0359j]
 [ 0.0656+0.775j   0.4241+1.7407j]
 [ 0.0862+0.9547j  0.4668+1.7866j]
 [-0.8242+0.6706j  0.2277+1.1032j]]
RX Waveform Data:
 [ 0.0126-0.0086j  0.0055+0.0029j -0.0135+0.0006j -0.0057+0.0084j]
NMSE: 5.4597016465344875e-05
[ ]: