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 
32 NS_LOG_COMPONENT_DEFINE("SatMutualInformationTable");
33 
34 namespace ns3
35 {
36 
37 NS_OBJECT_ENSURE_REGISTERED(SatMutualInformationTable);
38 
39 SatMutualInformationTable::SatMutualInformationTable(std::string mutualInformationPath)
40  : m_beta(1.0)
41 {
42  NS_LOG_FUNCTION(this << mutualInformationPath);
43  Load(mutualInformationPath);
44 }
45 
47 {
48  NS_LOG_FUNCTION(this);
49 }
50 
51 void
53 {
54  NS_LOG_FUNCTION(this);
55 
56  m_snirDb.clear();
57  m_symbolInformation.clear();
58 
59  if (m_ifs != 0)
60  {
61  if (m_ifs->is_open())
62  {
63  m_ifs->close();
64  }
65 
66  delete m_ifs;
67  m_ifs = 0;
68  }
69 
70  Object::DoDispose();
71 }
72 
73 TypeId
75 {
76  static TypeId tid = TypeId("ns3::SatMutualInformationTable")
77  .SetParent<Object>()
78  .AddAttribute("Beta",
79  "The adjusting factor for the MI function",
80  DoubleValue(1.0),
81  MakeDoubleAccessor(&SatMutualInformationTable::m_beta),
82  MakeDoubleChecker<double>());
83  return tid;
84 }
85 
86 double
88 {
89  NS_LOG_FUNCTION(this << snirDb);
90  NS_LOG_INFO("SatMutualInformationTable::GetNormalizedSymbolInformation - SNIR dB=" << snirDb);
91 
92  uint16_t n = m_snirDb.size();
93 
94  NS_ASSERT(n > 0);
95  NS_ASSERT(m_symbolInformation.size() == n);
96 
97  if (snirDb < m_snirDb[0])
98  {
99  // edge case: very low SNIR, return minimum Symbol Information
100  NS_LOG_INFO(this << " Very low SNIR -> Symbol Information = 0.0");
101  return 0.0;
102  }
103 
104  uint16_t i = 1;
105 
106  while ((i < n) && (snirDb > m_snirDb[i]))
107  {
108  i++;
109  }
110 
111  NS_LOG_DEBUG(this << " i=" << i << " snir[i]=" << m_snirDb[i]
112  << " symbolInformation[i]=" << m_symbolInformation[i]);
113 
114  if (i >= n)
115  {
116  // edge case: very high SNIR, return maximum Symbol Information
117  NS_LOG_INFO(this << " Very high SNIR -> Symbol Information = 1.0");
118  return 1.0;
119  }
120  else // snirDb <= m_snirDb[i]
121  {
122  // normal case
123  NS_ASSERT(i > 0);
124  NS_ASSERT(i < n);
125 
126  double snir = snirDb;
127  double snir0 = m_snirDb[i - 1];
128  double snir1 = m_snirDb[i];
129  double symbolInformation = SatUtils::Interpolate(snir,
130  snir0,
131  snir1,
132  m_symbolInformation[i - 1],
134  NS_LOG_INFO(this << " Interpolate: " << snir << " to Symbol Information = "
135  << symbolInformation << "(snir0: " << snir0 << ", snir1: " << snir1
136  << ", symbolInformation0: " << m_symbolInformation[i - 1]
137  << ", symbolInformation1: " << m_symbolInformation[i] << ")");
138 
139  return symbolInformation;
140  }
141 
142 } // end of double SatMutualInformationTable::GetNormalizedSymbolInformation (double snirDb) const
143 
144 double
145 SatMutualInformationTable::GetSnirDb(double symbolInformationTarget) const
146 {
147  NS_LOG_FUNCTION(this << symbolInformationTarget);
148  NS_LOG_INFO("SatMutualInformationTable::GetSnirDb - Symbol Information Target="
149  << symbolInformationTarget);
150 
151  uint16_t n = m_symbolInformation.size();
152 
153  NS_ASSERT(n > 0);
154  NS_ASSERT(m_snirDb.size() == n);
155 
156  // If the requested Symbol Information is smaller than the smallest Symbol Information entry
157  // in the look-up-table. Return small value
158  if (symbolInformationTarget <= m_symbolInformation[0])
159  {
160  NS_LOG_INFO("SatMutualInformationTable::GetSnirDb - SNIR dB=" << -1.0e10);
161  return -1.0e10;
162  }
163 
164  // The requested Symbol Information is higher than the highest Symbol Information entry
165  // in the look-up-table
166  if (symbolInformationTarget > 1.0)
167  {
168  NS_FATAL_ERROR("The Symbol Information target is set to be too high!");
169  }
170 
171  // The requested Symbol Information is higher than the highest Symbol Information entry
172  // in the look-up-table
173  if (symbolInformationTarget > m_symbolInformation[n - 1])
174  {
175  NS_LOG_INFO("SatMutualInformationTable::GetSnirDb - SNIR dB=" << m_snirDb[n - 1]);
176  return m_snirDb[n - 1];
177  }
178 
179  double snir = 0.0;
180  // Go through the list from end to beginning
181  for (uint32_t i = 0; i < n; ++i)
182  {
183  if (symbolInformationTarget <= m_symbolInformation[i])
184  {
185  snir = SatUtils::Interpolate(symbolInformationTarget,
186  m_symbolInformation[i - 1],
188  m_snirDb[i - 1],
189  m_snirDb[i]);
190  NS_LOG_INFO(this << " Interpolate: " << symbolInformationTarget << " to snir = " << snir
191  << "(symbolInformation0: " << m_symbolInformation[i - 1]
192  << ", symbolInformation1: " << m_symbolInformation[i] << ", snir0: "
193  << m_snirDb[i - 1] << ", snir1: " << m_snirDb[i] << ")");
194  return snir;
195  }
196  }
197 
198  return snir;
199 } // end of double SatMutualInformationTable::GetSnir (double symbolInformationTarget) const
200 
201 void
202 SatMutualInformationTable::Load(std::string mutualInformationPath)
203 {
204  NS_LOG_FUNCTION(this << mutualInformationPath);
205 
206  // READ FROM THE SPECIFIED INPUT FILE
207 
208  m_ifs = new std::ifstream(mutualInformationPath.c_str(), std::ifstream::in);
209 
210  if (!m_ifs->is_open())
211  {
212  // script might be launched by test.py, try a different base path
213  delete m_ifs;
214  mutualInformationPath = "../../" + mutualInformationPath;
215  m_ifs = new std::ifstream(mutualInformationPath.c_str(), std::ifstream::in);
216 
217  if (!m_ifs->is_open())
218  {
219  NS_FATAL_ERROR("The file " << mutualInformationPath << " is not found.");
220  }
221  }
222 
223  double lastSnirDb = -100.0; //-1.0e100; // very low value
224  double lastSymbolInformation = 0.0; // minimum value
225 
226  double snirDb, symbolInformation;
227  *m_ifs >> snirDb >> symbolInformation;
228 
229  while (m_ifs->good())
230  {
231  NS_LOG_DEBUG(this << " snirDb=" << snirDb << ", symbolInformation=" << symbolInformation);
232 
233  // SANITY CHECK PART I
234  if ((snirDb <= lastSnirDb) || (symbolInformation < lastSymbolInformation))
235  {
236  NS_FATAL_ERROR("The file " << mutualInformationPath << " is not properly sorted.");
237  }
238 
239  // record the values
240  m_snirDb.push_back(snirDb);
241  m_symbolInformation.push_back(symbolInformation);
242  lastSnirDb = snirDb;
243  lastSymbolInformation = symbolInformation;
244 
245  // get next row
246  *m_ifs >> snirDb >> symbolInformation;
247  }
248 
249  m_ifs->close();
250  delete m_ifs;
251  m_ifs = 0;
252 
253  // SANITY CHECK PART II
254 
255  // at least contains one row
256  if (m_snirDb.empty())
257  {
258  NS_FATAL_ERROR("Error reading data from file " << mutualInformationPath << ".");
259  }
260 
261  // SNIR and BLER have same size
262  NS_ASSERT(m_snirDb.size() == m_symbolInformation.size());
263 
264 } // end of void Load (std::string mutualInformationPath)
265 
266 } // 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.