Loading...
Searching...
No Matches
satellite-mutual-information-table.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2018 CNES
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Joaquin Muguerza <joaquin.muguerza@viveris.fr>
19 *
20 */
21
23
24#include "satellite-utils.h"
25
26#include "ns3/double.h"
27#include "ns3/fatal-error.h"
28#include "ns3/log.h"
29
30#include <cmath>
31#include <fstream>
32#include <stdint.h>
33#include <string>
34
35NS_LOG_COMPONENT_DEFINE("SatMutualInformationTable");
36
37namespace ns3
38{
39
40NS_OBJECT_ENSURE_REGISTERED(SatMutualInformationTable);
41
43 : m_beta(1.0)
44{
45 NS_LOG_FUNCTION(this << mutualInformationPath);
46 Load(mutualInformationPath);
47}
48
53
54void
56{
57 NS_LOG_FUNCTION(this);
58
59 m_snirDb.clear();
60 m_symbolInformation.clear();
61
62 if (m_ifs != 0)
63 {
64 if (m_ifs->is_open())
65 {
66 m_ifs->close();
67 }
68
69 delete m_ifs;
70 m_ifs = 0;
71 }
72
73 Object::DoDispose();
74}
75
76TypeId
78{
79 static TypeId tid = TypeId("ns3::SatMutualInformationTable")
80 .SetParent<Object>()
81 .AddAttribute("Beta",
82 "The adjusting factor for the MI function",
83 DoubleValue(1.0),
84 MakeDoubleAccessor(&SatMutualInformationTable::m_beta),
85 MakeDoubleChecker<double>());
86 return tid;
87}
88
89double
91{
92 NS_LOG_FUNCTION(this << snirDb);
93 NS_LOG_INFO("SatMutualInformationTable::GetNormalizedSymbolInformation - SNIR dB=" << snirDb);
94
95 uint16_t n = m_snirDb.size();
96
97 NS_ASSERT(n > 0);
98 NS_ASSERT(m_symbolInformation.size() == n);
99
100 if (snirDb < m_snirDb[0])
101 {
102 // edge case: very low SNIR, return minimum Symbol Information
103 NS_LOG_INFO(this << " Very low SNIR -> Symbol Information = 0.0");
104 return 0.0;
105 }
106
107 uint16_t i = 1;
108
109 while ((i < n) && (snirDb > m_snirDb[i]))
110 {
111 i++;
112 }
113
114 NS_LOG_DEBUG(this << " i=" << i << " snir[i]=" << m_snirDb[i]
115 << " symbolInformation[i]=" << m_symbolInformation[i]);
116
117 if (i >= n)
118 {
119 // edge case: very high SNIR, return maximum Symbol Information
120 NS_LOG_INFO(this << " Very high SNIR -> Symbol Information = 1.0");
121 return 1.0;
122 }
123 else // snirDb <= m_snirDb[i]
124 {
125 // normal case
126 NS_ASSERT(i > 0);
127 NS_ASSERT(i < n);
128
129 double snir = snirDb;
130 double snir0 = m_snirDb[i - 1];
131 double snir1 = m_snirDb[i];
132 double symbolInformation = SatUtils::Interpolate(snir,
133 snir0,
134 snir1,
135 m_symbolInformation[i - 1],
137 NS_LOG_INFO(this << " Interpolate: " << snir << " to Symbol Information = "
138 << symbolInformation << "(snir0: " << snir0 << ", snir1: " << snir1
139 << ", symbolInformation0: " << m_symbolInformation[i - 1]
140 << ", symbolInformation1: " << m_symbolInformation[i] << ")");
141
142 return symbolInformation;
143 }
144
145} // end of double SatMutualInformationTable::GetNormalizedSymbolInformation (double snirDb) const
146
147double
148SatMutualInformationTable::GetSnirDb(double symbolInformationTarget) const
149{
150 NS_LOG_FUNCTION(this << symbolInformationTarget);
151 NS_LOG_INFO("SatMutualInformationTable::GetSnirDb - Symbol Information Target="
152 << symbolInformationTarget);
153
154 uint16_t n = m_symbolInformation.size();
155
156 NS_ASSERT(n > 0);
157 NS_ASSERT(m_snirDb.size() == n);
158
159 // If the requested Symbol Information is smaller than the smallest Symbol Information entry
160 // in the look-up-table. Return small value
161 if (symbolInformationTarget <= m_symbolInformation[0])
162 {
163 NS_LOG_INFO("SatMutualInformationTable::GetSnirDb - SNIR dB=" << -1.0e10);
164 return -1.0e10;
165 }
166
167 // The requested Symbol Information is higher than the highest Symbol Information entry
168 // in the look-up-table
169 if (symbolInformationTarget > 1.0)
170 {
171 NS_FATAL_ERROR("The Symbol Information target is set to be too high!");
172 }
173
174 // The requested Symbol Information is higher than the highest Symbol Information entry
175 // in the look-up-table
176 if (symbolInformationTarget > m_symbolInformation[n - 1])
177 {
178 NS_LOG_INFO("SatMutualInformationTable::GetSnirDb - SNIR dB=" << m_snirDb[n - 1]);
179 return m_snirDb[n - 1];
180 }
181
182 double snir = 0.0;
183 // Go through the list from end to beginning
184 for (uint32_t i = 0; i < n; ++i)
185 {
186 if (symbolInformationTarget <= m_symbolInformation[i])
187 {
188 snir = SatUtils::Interpolate(symbolInformationTarget,
189 m_symbolInformation[i - 1],
191 m_snirDb[i - 1],
192 m_snirDb[i]);
193 NS_LOG_INFO(this << " Interpolate: " << symbolInformationTarget << " to snir = " << snir
194 << "(symbolInformation0: " << m_symbolInformation[i - 1]
195 << ", symbolInformation1: " << m_symbolInformation[i] << ", snir0: "
196 << m_snirDb[i - 1] << ", snir1: " << m_snirDb[i] << ")");
197 return snir;
198 }
199 }
200
201 return snir;
202} // end of double SatMutualInformationTable::GetSnir (double symbolInformationTarget) const
203
204void
205SatMutualInformationTable::Load(std::string mutualInformationPath)
206{
207 NS_LOG_FUNCTION(this << mutualInformationPath);
208
209 // READ FROM THE SPECIFIED INPUT FILE
210
211 m_ifs = new std::ifstream(mutualInformationPath.c_str(), std::ifstream::in);
212
213 if (!m_ifs->is_open())
214 {
215 // script might be launched by test.py, try a different base path
216 delete m_ifs;
217 mutualInformationPath = "../../" + mutualInformationPath;
218 m_ifs = new std::ifstream(mutualInformationPath.c_str(), std::ifstream::in);
219
220 if (!m_ifs->is_open())
221 {
222 NS_FATAL_ERROR("The file " << mutualInformationPath << " is not found.");
223 }
224 }
225
226 double lastSnirDb = -100.0; //-1.0e100; // very low value
227 double lastSymbolInformation = 0.0; // minimum value
228
229 double snirDb, symbolInformation;
230 *m_ifs >> snirDb >> symbolInformation;
231
232 while (m_ifs->good())
233 {
234 NS_LOG_DEBUG(this << " snirDb=" << snirDb << ", symbolInformation=" << symbolInformation);
235
236 // SANITY CHECK PART I
237 if ((snirDb <= lastSnirDb) || (symbolInformation < lastSymbolInformation))
238 {
239 NS_FATAL_ERROR("The file " << mutualInformationPath << " is not properly sorted.");
240 }
241
242 // record the values
243 m_snirDb.push_back(snirDb);
244 m_symbolInformation.push_back(symbolInformation);
245 lastSnirDb = snirDb;
246 lastSymbolInformation = symbolInformation;
247
248 // get next row
249 *m_ifs >> snirDb >> symbolInformation;
250 }
251
252 m_ifs->close();
253 delete m_ifs;
254 m_ifs = 0;
255
256 // SANITY CHECK PART II
257
258 // at least contains one row
259 if (m_snirDb.empty())
260 {
261 NS_FATAL_ERROR("Error reading data from file " << mutualInformationPath << ".");
262 }
263
264 // SNIR and BLER have same size
265 NS_ASSERT(m_snirDb.size() == m_symbolInformation.size());
266
267} // end of void Load (std::string mutualInformationPath)
268
269} // end of namespace ns3
Loads a mutual information file and provide query service.
double GetNormalizedSymbolInformation(double snirDb) const
Get the Normalized Symbol Information corresponding to a given SNIR.
virtual ~SatMutualInformationTable()
Destructor for SatMutualInformationTable.
void Load(std::string mutualInformationPath)
Load the mutual information.
double GetSnirDb(double symbolInformationTarget) const
Get the SNIR in dB for a given Normalized Symbol Information target.
SatMutualInformationTable(std::string mutualInformationPath)
Constructor with initialization parameters.
static double Interpolate(double x, double x0, double x1, double y0, double y1)
Simple linear interpolation.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.