5#include "nr-pm-search-full.h"
7#include <ns3/boolean.h>
8#include <ns3/simulator.h>
9#include <ns3/uinteger.h>
16NS_LOG_COMPONENT_DEFINE(
"NrPmSearchFull");
17NS_OBJECT_ENSURE_REGISTERED(NrPmSearchFull);
22 static TypeId tid = TypeId(
"ns3::NrPmSearchFull")
24 .AddConstructor<NrPmSearchFull>()
25 .AddAttribute(
"CodebookType",
26 "Codebook class to be used",
42 NS_LOG_FUNCTION(
this);
68 NS_LOG_FUNCTION(
this);
71 auto nRows = rxSignalRb.
m_chanMat.GetNumRows();
72 auto nCols = rxSignalRb.
m_chanMat.GetNumCols();
73 NS_ASSERT_MSG(nRows ==
m_nRxPorts,
"Channel mat has {} rows but UE has {} ports");
74 NS_ASSERT_MSG(nCols ==
m_nGnbPorts,
"Channel mat has {} cols but gNB has {} ports");
83 auto optPrecForRanks = std::vector<PmCqiInfo>{};
87 optPrecForRanks.emplace_back(std::move(cqiMsg));
89 if (optPrecForRanks.back().m_wbCqi == 0)
91 if (optPrecForRanks.size() >= 2)
93 optPrecForRanks.pop_back();
100 auto optRankCqiMsg = *std::max_element(
101 optPrecForRanks.begin(),
102 optPrecForRanks.end(),
104 return optRankCqiMsg;
130 std::vector<Ptr<PrecMatParams>> optSubbandPrecoders{};
132 for (
auto i1 =
size_t{0}; i1 < numI1; i1++)
138 optSubbandPrecoders.emplace_back(subbandParams);
143 *std::max_element(optSubbandPrecoders.begin(),
144 optSubbandPrecoders.end(),
145 [](
const Ptr<PrecMatParams>& a,
const Ptr<PrecMatParams>& b) {
146 return a->perfMetric < b->perfMetric;
161 auto wbPmi = optPrec->wbPmi;
171 NS_ASSERT_MSG(optPrec,
"Tried to create a CQI message but precoding matrix does not exist");
174 auto rbPrecMat =
SubbandUpsampling(optPrec->sbPrecMat, rbNormChanMat.GetNumPages());
185 for (
auto& sbCqi : mcsParams.sbCqis)
187 auto diff = (int)sbCqi - (
int)mcsParams.wbCqi;
190 sbCqi = mcsParams.wbCqi + 2;
194 sbCqi = mcsParams.wbCqi - 1;
201 .
m_mcs = mcsParams.mcs,
203 .m_wbPmi = optPrec->wbPmi,
204 .m_wbCqi = mcsParams.wbCqi,
205 .m_sbCqis = mcsParams.sbCqis,
206 .m_sbPmis = optPrec->sbPmis,
207 .m_optPrecMat = Create<const ComplexMatrixArray>(std::move(rbPrecMat)),
208 .m_tbSize = mcsParams.tbSize,
213Ptr<NrPmSearchFull::PrecMatParams>
220 auto nSubbands = sbNormChanMat.GetNumPages();
223 auto numI2 = allPrecMats.size();
226 auto sbPmis = std::vector<size_t>(nSubbands);
227 auto optSubbandMetric = DoubleMatrixArray{nSubbands};
228 auto optPrecMat = allPrecMats[0];
229 for (
auto iSb =
size_t{0}; iSb < nSubbands; iSb++)
232 for (
auto i2 =
size_t{0}; i2 < numI2; i2++)
234 if (subbandMetricForPrec(iSb, i2) > optSubbandMetric(iSb))
237 optSubbandMetric(iSb) = subbandMetricForPrec(iSb, i2);
241 for (
size_t i = 0; i < optPrecMat.GetNumRows(); i++)
243 for (
size_t j = 0; j < optPrecMat.GetNumCols(); j++)
245 optPrecMat(i, j, iSb) = allPrecMats[sbPmis[iSb]](i, j, iSb);
249 auto widebandMetric = optSubbandMetric.GetValues().sum();
251 auto res = Create<NrPmSearchFull::PrecMatParams>();
253 res->sbPmis = sbPmis;
254 res->sbPrecMat = optPrecMat;
255 res->perfMetric = widebandMetric;
259std::vector<ComplexMatrixArray>
263 auto numI2 = cb->GetNumI2();
265 std::vector<ComplexMatrixArray> allPrecMats;
267 for (
auto i2 =
size_t{0}; i2 < numI2; i2++)
269 auto basePrecMat = cb->GetBasePrecMat(i1, i2);
270 auto sbPrecMat = ExpandPrecodingMatrix(basePrecMat, nSubbands);
271 allPrecMats.emplace_back(sbPrecMat);
277NrPmSearchFull::ExpandPrecodingMatrix(ComplexMatrixArray basePrecMat,
size_t nSubbands)
279 NS_ASSERT_MSG(basePrecMat.GetNumPages() == 1,
"Expanding to 3D requires a 2D input");
280 auto nRows = basePrecMat.GetNumRows();
281 auto nCols = basePrecMat.GetNumCols();
282 ComplexMatrixArray res{nRows, nCols, nSubbands};
283 for (
size_t p = 0; p < nSubbands; p++)
285 for (
size_t i = 0; i < nRows; i++)
287 for (
size_t j = 0; j < nCols; j++)
289 res(i, j, p) = basePrecMat(i, j);
298 std::vector<ComplexMatrixArray> allPrecMats)
const
300 auto nSubbands = sbNormChanMat.GetNumPages();
301 auto numI2 = allPrecMats.size();
303 DoubleMatrixArray subbandCap{nSubbands, numI2};
304 for (
auto i2 =
size_t{0}; i2 < numI2; i2++)
306 const auto& sbPrecMat = allPrecMats[i2];
308 for (
auto iSb =
size_t{0}; iSb < nSubbands; iSb++)
311 for (
size_t iLayer = 0; iLayer < sinr.GetNumRows(); iLayer++)
313 currCap += log2(1.0 + sinr(iLayer, iSb));
315 subbandCap(iSb, i2) = currCap;
static TypeId GetTypeId()
Get TypeId.
Wrapper class for implementations of Type-I precoding matrices in 3GPP TS 38.214. A separate object m...
virtual void Init()=0
Initialize the codebook parameters after construction, based on attribute values.
virtual NrIntfNormChanMat CalcIntfNormChannel(const ComplexMatrixArray &chanMat) const
Calculate the interference-normalized channel matrix for SISO and MIMO. See NrIntfNormChanMat for det...
virtual NrSinrMatrix ComputeSinrForPrecoding(const ComplexMatrixArray &precMats) const
Compute the MIMO SINR when a specific precoder is applied.
PmCqiInfo CreateCqiForRank(uint8_t rank, const NrIntfNormChanMat &rbNormChanMat) const
Create CQI feedback message for a particular rank.
PmCqiInfo CreateCqiFeedbackMimo(const NrMimoSignal &rxSignalRb, PmiUpdate pmiUpdate) override
Create CQI feedback with optimal rank, optimal PMI, and corresponding CQI values. Optimal rank is con...
std::vector< RankParams > m_rankParams
The parameters (PMI values, codebook) for each rank.
void UpdateAllPrecoding(const NrIntfNormChanMat &rbNormChanMat)
For all ranks, update the optimum precoding matrices (wideband and subband).
Ptr< PrecMatParams > FindOptSubbandPrecoding(const NrIntfNormChanMat &sbNormChanMat, size_t i1, uint8_t rank) const
Find the optimal subband precoding matrix for the given wideband precoding.
ObjectFactory m_cbFactory
The factory used to create the codebooks.
void SetCodebookTypeId(const TypeId &typeId)
Set the TypeId of the codebook (NrCbTypeOne) to be used.
static TypeId GetTypeId()
Get TypeId.
void InitCodebooks() override
Create and initialize the codebook for each rank.
void ConditionallyUpdatePrecoding(const NrIntfNormChanMat &rbNormChanMat, PmiUpdate pmiUpdate)
Update the WB and/or SB PMI, or neither.
std::vector< ComplexMatrixArray > CreateSubbandPrecoders(size_t i1, uint8_t rank, size_t nSubbands) const
Create the subband precoding matrices for the given wideband precoding.
void UpdateSubbandPrecoding(const NrIntfNormChanMat &rbNormChanMat)
For all ranks, update the opt subband PMI assuming previous value of wideband PMI.
DoubleMatrixArray ComputeCapacityForPrecoders(const NrIntfNormChanMat &sbNormChanMat, std::vector< ComplexMatrixArray > allPrecMats) const
Compute the Shannon capacity for each possible precoding matrix in each subband.
void SetCodebookAttribute(const std::string &attrName, const AttributeValue &attrVal)
Set the ns-3 attribute of the codebook (NrCbTypeOne).
Base class for searching optimal precoding matrices and creating full CQI/PMI feedback This is a most...
uint8_t m_rankLimit
Limit the UE's maximum supported rank.
size_t m_nRxPorts
Number of receive ports at this UE.
size_t m_nGnbHPorts
Number of horizontal ports in the gNB antenna array.
Ptr< const NrAmc > m_amc
The NrAmc to be used for computing TB size and MCS.
size_t m_nGnbPorts
Total number of ports in the gNB antenna array.
std::vector< uint8_t > m_ranks
The set of ranks for which to compute precoding matrices.
virtual NrIntfNormChanMat SubbandUpsampling(const NrIntfNormChanMat &precMat, size_t numPrbs) const
Upsample the input per-subband precoding matrix into a per-PRB precoding matrix.
bool m_isGnbDualPol
True when gNB has a dual-polarized antenna array.
virtual NrIntfNormChanMat SubbandDownsampling(const NrIntfNormChanMat &channelMatrix)
Downsample the input channel matrix into bins of at most m_subbandSize PRBs.
size_t m_subbandSize
Size of each subband (in number of RBs)
size_t m_nGnbVPorts
Number of vertical ports in the gNB antenna array.
bool m_subbandCqiClamping
Helper struct for processing and storing received signals for use in CSI feedback.
NrCovMat m_covMat
Interference and noise covariance matrix; nRxPorts * nRxPorts * nRbs.
ComplexMatrixArray m_chanMat
Channel Matrix; nRxPorts * nTxPorts * nRbs.
Parameters that define if PMI should be updated or if previous PMI values are used.
bool updateWb
Defines whether to update WB PMI.
bool updateSb
Defines whether to update SB PMI.
The structure used for the CQI feedback message that contains the optimum CQI, RI,...
uint8_t m_mcs
Modulation and coding scheme supported by current channel.