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 
35 NS_LOG_COMPONENT_DEFINE("SatMutualInformationTable");
36 
37 namespace ns3
38 {
39 
40 NS_OBJECT_ENSURE_REGISTERED(SatMutualInformationTable);
41 
42 SatMutualInformationTable::SatMutualInformationTable(std::string mutualInformationPath)
43  : m_beta(1.0)
44 {
45  NS_LOG_FUNCTION(this << mutualInformationPath);
46  Load(mutualInformationPath);
47 }
48 
50 {
51  NS_LOG_FUNCTION(this);
52 }
53 
54 void
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 
76 TypeId
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 
89 double
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 
147 double
148 SatMutualInformationTable::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 
204 void
205 SatMutualInformationTable::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
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.