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
[ ]: