DESERT 3.5.1
Loading...
Searching...
No Matches
mclinkextended.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2021 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
39#include <string.h>
40#include <rng.h>
41#include <tclcl.h>
42#include <iostream>
43#include <array>
44#include "mclinkextended.h"
45
46static class MCLinkExtendedClass : public TclClass
47{
48public:
50 : TclClass("Module/UW/HMMPHYSICAL/MCLINK/EXTENDED")
51 {
52 }
53 TclObject *
54 create(int argc, const char *const * argv)
55 {
56 if (argc > 13) {
57 if (argc == 14 || argc == 15) {
58
59 if (argc == 14) {
60 return (new MCLinkExtended(std::stod(argv[4]), std::stod(argv[5]),
61 std::stod(argv[6]), std::stod(argv[7]), std::stod(argv[8]),
62 std::stod(argv[9]), std::stod(argv[10]), std::stod(argv[11]),
63 std::stod(argv[12]), std::stod(argv[13])));
64 }
65 if (argc == 15) {
67 if (strcasecmp(argv[14], "GOOD") == 0) {
68 ch_state = MCLinkExtended::GOOD;
69 } else if (strcasecmp(argv[14], "MEDIUM") == 0) {
70 ch_state = MCLinkExtended::MEDIUM;
71 } else if (strcasecmp(argv[14], "BAD") == 0) {
72 ch_state = MCLinkExtended::BAD;
73 } else {
74 std::cerr << "TCL: MCLinkExtended state must be GOOD, MEDIUM or BAD"
75 << std::endl;
76 exit(1);
77 }
78 return (new MCLinkExtended(std::stod(argv[4]), std::stod(argv[5]),
79 std::stod(argv[6]), std::stod(argv[7]), std::stod(argv[8]),
80 std::stod(argv[9]), std::stod(argv[10]), std::stod(argv[11]),
81 std::stod(argv[12]),std::stod(argv[13]), ch_state));
82 }
83 }
84 std::cerr << "TCL: check MCLinkExtended constructor args" << std::endl;
85 exit(1);
86 }
87
88 return (new MCLinkExtended);
89 }
91
93 : MCLink()
94 , ber_medium(0.0)
95 , p_gm(0.0)
96 , p_mg(0.0)
97 , p_mb(0.0)
98 , p_bm(0.0)
99 , P{{1.0 - p_gm - p_gb, p_gm, p_gb}, {p_mg, 1.0 - p_mg - p_mb, p_mb},
100 {p_bg, p_bm, 1.0 - p_bg - p_bm}}
101{
102}
103
104MCLinkExtended::MCLinkExtended(double ber_good, double ber_medium,
105 double ber_bad, double p_gb, double p_gm, double p_mg, double p_mb, double p_bg,
106 double p_bm, double step_period, ChState ch_state)
107 : MCLink(ber_good, ber_bad, p_gb, p_bg, step_period, ch_state)
108 , ber_medium(ber_medium)
109 , p_gm(p_gm)
110 , p_mg(p_mg)
111 , p_mb(p_mb)
112 , p_bm(p_bm)
113 , P{{1.0 - p_gm - p_gb, p_gm, p_gb}, {p_mg, 1.0 - p_mg - p_mb, p_mb},
114 {p_bg, p_bm, 1.0 - p_bg - p_bm}}
115{
116 assert(ber_good >=0.0 && ber_good <= 1.0 &&
117 ber_medium >= 0.0 && ber_medium <= 1.0 &&
118 ber_bad >= 0.0 && ber_bad <= 1.0 &&
119 p_gb >= 0.0 && p_gb <= 1.0 && p_gm >= 0.0 && p_gm <= 1.0 &&
120 p_mg >= 0.0 && p_mg <= 1.0 && p_mb >= 0.0 && p_mb <= 1.0 &&
121 p_bg >= 0.0 && p_bg <= 1.0 && p_bm >= 0.0 && p_bm <= 1.0);
122}
123
124void
125MCLinkExtended::mul_matrix (double (&A)[3][3], const double (&B)[3][3])
126{
127 double C[3][3] = {0};
128
129 for (int i = 0; i < 3; i++) {
130 for (int j = 0; j < 3; j++) {
131 for (int k = 0; k < 3; k++) {
132 C[i][j] = (C[i][j] + A[i][k] * B[k][j]);
133 }
134 }
135 }
136
137 for (int i = 0; i < 3; i++) {
138 for (int j = 0; j < 3; j++) {
139 A[i][j] = C[i][j];
140 }
141 }
142}
143
144void
145MCLinkExtended::pow_matrix(const double (&A)[3][3], int n, double (&R)[3][3])
146{
147 double B[3][3];
148
149 for (int i = 0; i < 3; i++) {
150 for (int j = 0; j < 3; j++) {
151 B[i][j] = A[i][j];
152 R[i][j] = A[i][j];
153 }
154 }
155
156 n--;
157 while (n > 0)
158 {
159 if (n % 2) {
160 mul_matrix(R, const_cast<double (&)[3][3]>(B));
161 }
162 mul_matrix(B, const_cast<double (&)[3][3]>(B));
163 n = n >> 1;
164 }
165}
166
169{
170 int n_step = floor((NOW - last_update) / step_period);
171 if (n_step == 0) {
172 return ch_state;
173 }
174
175 double P_n[3][3] = {0.0};
176 pow_matrix(const_cast<double (&)[3][3]>(P), n_step, P_n);
177
179 double new_p_gg = P_n[0][0];
180 double new_p_gm = P_n[0][1];
181 double rng = RNG::defaultrng()->uniform_double();
182 if (rng > new_p_gg + new_p_gm) {
184 } else if (rng > new_p_gg) {
186 }
187 } else if (ch_state == MCLinkExtended::MEDIUM) {
188 double new_p_mg = P_n[1][0];
189 double new_p_mm = P_n[1][1];
190 double rng = RNG::defaultrng()->uniform_double();
191 if (rng > new_p_mm + new_p_mg) {
193 } else if (rng > new_p_mm) {
195 }
196 } else if (ch_state == MCLinkExtended::BAD) {
197 double new_p_bg = P_n[2][0];
198 double new_p_bb = P_n[2][2];
199 double rng = RNG::defaultrng()->uniform_double();
200 if (rng > new_p_bb + new_p_bg) {
202 } else if (rng > new_p_bb) {
204 }
205 }
206 last_update += n_step * step_period;
207 return ch_state;
208}
209
210double
212{
214 if (ch_state == GOOD) {
215 return ber_good;
216 } else if (ch_state == MEDIUM) {
217 return ber_medium;
218 } else {
219 return ber_bad;
220 }
221}
222
223int
224MCLinkExtended::command(int argc, const char *const *argv)
225{
226 Tcl &tcl = Tcl::instance();
227
228 if (argc == 2) {
229 if (strcasecmp(argv[1], "getChState") == 0) {
230 tcl.resultf("%d", getChState());
231 return TCL_OK;
232 } else
233 if (strcasecmp(argv[1], "getBER") == 0) {
234 tcl.resultf("%f", getBER());
235 return TCL_OK;
236 }
237 }
238 std::cerr << "TCL: unknown MCLinkExtended command" << std::endl;
239 return TCL_ERROR;
240}
TclObject * create(int argc, const char *const *argv)
MCLinkExtended class stores and updates the probabilities and the channel state for UnderwaterHMMPhys...
MCLinkExtended()
Default constructor of MCLinkExtended class.
virtual double getBER() override
double P[3][3]
Transition matrix for the channel.
virtual ChState updateChState() override
Called upon packet reception, decides and returns the new channel state updates the members state and...
double p_gm
Prob of transition from good to medium channel.
double ber_medium
BER with medium channel.
void pow_matrix(const double(&A)[3][3], int n, double(&R)[3][3])
Auxiliary function raising a 3x3 matrix to the power of n.
virtual int command(int, const char *const *) override
TCL command interpreter.
void mul_matrix(double(&A)[3][3], const double(&B)[3][3])
Auxiliary function calculating the result of a 3x3 matrix multiplication; result is stored in first a...
MCLinkExtendedClass class_module_mclinkextended
Definition of MCLinkExtended class, extending MCLink.