42 } |
44 } |
43 |
45 |
44 double |
46 double |
45 NistErrorRateModel::GetBpskBer (double snr) const |
47 NistErrorRateModel::GetBpskBer (double snr) const |
46 { |
48 { |
47 double z = sqrt (snr); |
49 double z = std::sqrt (snr); |
48 double ber = 0.5 * erfc (z); |
50 double ber = 0.5 * erfc (z); |
49 NS_LOG_INFO ("bpsk snr=" << snr << " ber=" << ber); |
51 NS_LOG_INFO ("bpsk snr=" << snr << " ber=" << ber); |
50 return ber; |
52 return ber; |
51 } |
53 } |
52 double |
54 double |
53 NistErrorRateModel::GetQpskBer (double snr) const |
55 NistErrorRateModel::GetQpskBer (double snr) const |
54 { |
56 { |
55 double z = sqrt (snr / 2.0); |
57 double z = std::sqrt (snr / 2.0); |
56 double ber = 0.5 * erfc (z); |
58 double ber = 0.5 * erfc (z); |
57 NS_LOG_INFO ("qpsk snr=" << snr << " ber=" << ber); |
59 NS_LOG_INFO ("qpsk snr=" << snr << " ber=" << ber); |
58 return ber; |
60 return ber; |
59 } |
61 } |
60 double |
62 double |
61 NistErrorRateModel::Get16QamBer (double snr) const |
63 NistErrorRateModel::Get16QamBer (double snr) const |
62 { |
64 { |
63 double z = sqrt (snr / (5.0 * 2.0)); |
65 double z = std::sqrt (snr / (5.0 * 2.0)); |
64 double ber = 0.75 * 0.5 * erfc (z); |
66 double ber = 0.75 * 0.5 * erfc (z); |
65 NS_LOG_INFO ("16-Qam" << " snr=" << snr << " ber=" << ber); |
67 NS_LOG_INFO ("16-Qam" << " snr=" << snr << " ber=" << ber); |
66 return ber; |
68 return ber; |
67 } |
69 } |
68 double |
70 double |
69 NistErrorRateModel::Get64QamBer (double snr) const |
71 NistErrorRateModel::Get64QamBer (double snr) const |
70 { |
72 { |
71 double z = sqrt (snr / (21.0 * 2.0)); |
73 double z = std::sqrt (snr / (21.0 * 2.0)); |
72 double ber = 7.0 / 12.0 * 0.5 * erfc (z); |
74 double ber = 7.0 / 12.0 * 0.5 * erfc (z); |
73 NS_LOG_INFO ("64-Qam" << " snr=" << snr << " ber=" << ber); |
75 NS_LOG_INFO ("64-Qam" << " snr=" << snr << " ber=" << ber); |
74 return ber; |
76 return ber; |
75 } |
77 } |
76 double |
78 double |
96 { |
98 { |
97 return 1.0; |
99 return 1.0; |
98 } |
100 } |
99 double pe = CalculatePe (ber, bValue); |
101 double pe = CalculatePe (ber, bValue); |
100 pe = std::min (pe, 1.0); |
102 pe = std::min (pe, 1.0); |
101 double pms = pow (1 - pe, nbits); |
103 double pms = std::pow (1 - pe, nbits); |
102 return pms; |
104 return pms; |
103 } |
105 } |
104 double |
106 double |
105 NistErrorRateModel::CalculatePe (double p, uint32_t bValue) const |
107 NistErrorRateModel::CalculatePe (double p, uint32_t bValue) const |
106 { |
108 { |
107 double D = sqrt (4.0 * p * (1.0 - p)); |
109 double D = std::sqrt (4.0 * p * (1.0 - p)); |
108 double pe = 1.0; |
110 double pe = 1.0; |
109 if (bValue == 1) |
111 if (bValue == 1) |
110 { |
112 { |
111 // code rate 1/2, use table 3.1.1 |
113 // code rate 1/2, use table 3.1.1 |
112 pe = 0.5 * ( 36.0 * pow (D, 10.0) |
114 pe = 0.5 * ( 36.0 * std::pow (D, 10.0) |
113 + 211.0 * pow (D, 12.0) |
115 + 211.0 * std::pow (D, 12.0) |
114 + 1404.0 * pow (D, 14.0) |
116 + 1404.0 * std::pow (D, 14.0) |
115 + 11633.0 * pow (D, 16.0) |
117 + 11633.0 * std::pow (D, 16.0) |
116 + 77433.0 * pow (D, 18.0) |
118 + 77433.0 * std::pow (D, 18.0) |
117 + 502690.0 * pow (D, 20.0) |
119 + 502690.0 * std::pow (D, 20.0) |
118 + 3322763.0 * pow (D, 22.0) |
120 + 3322763.0 * std::pow (D, 22.0) |
119 + 21292910.0 * pow (D, 24.0) |
121 + 21292910.0 * std::pow (D, 24.0) |
120 + 134365911.0 * pow (D, 26.0) |
122 + 134365911.0 * std::pow (D, 26.0) |
121 ); |
123 ); |
122 } |
124 } |
123 else if (bValue == 2) |
125 else if (bValue == 2) |
124 { |
126 { |
125 // code rate 2/3, use table 3.1.2 |
127 // code rate 2/3, use table 3.1.2 |
126 pe = 1.0 / (2.0 * bValue) * |
128 pe = 1.0 / (2.0 * bValue) * |
127 ( 3.0 * pow (D, 6.0) |
129 ( 3.0 * std::pow (D, 6.0) |
128 + 70.0 * pow (D, 7.0) |
130 + 70.0 * std::pow (D, 7.0) |
129 + 285.0 * pow (D, 8.0) |
131 + 285.0 * std::pow (D, 8.0) |
130 + 1276.0 * pow (D, 9.0) |
132 + 1276.0 * std::pow (D, 9.0) |
131 + 6160.0 * pow (D, 10.0) |
133 + 6160.0 * std::pow (D, 10.0) |
132 + 27128.0 * pow (D, 11.0) |
134 + 27128.0 * std::pow (D, 11.0) |
133 + 117019.0 * pow (D, 12.0) |
135 + 117019.0 * std::pow (D, 12.0) |
134 + 498860.0 * pow (D, 13.0) |
136 + 498860.0 * std::pow (D, 13.0) |
135 + 2103891.0 * pow (D, 14.0) |
137 + 2103891.0 * std::pow (D, 14.0) |
136 + 8784123.0 * pow (D, 15.0) |
138 + 8784123.0 * std::pow (D, 15.0) |
137 ); |
139 ); |
138 } |
140 } |
139 else if (bValue == 3) |
141 else if (bValue == 3) |
140 { |
142 { |
141 // code rate 3/4, use table 3.1.2 |
143 // code rate 3/4, use table 3.1.2 |
142 pe = 1.0 / (2.0 * bValue) * |
144 pe = 1.0 / (2.0 * bValue) * |
143 ( 42.0 * pow (D, 5.0) |
145 ( 42.0 * std::pow (D, 5.0) |
144 + 201.0 * pow (D, 6.0) |
146 + 201.0 * std::pow (D, 6.0) |
145 + 1492.0 * pow (D, 7.0) |
147 + 1492.0 * std::pow (D, 7.0) |
146 + 10469.0 * pow (D, 8.0) |
148 + 10469.0 * std::pow (D, 8.0) |
147 + 62935.0 * pow (D, 9.0) |
149 + 62935.0 * std::pow (D, 9.0) |
148 + 379644.0 * pow (D, 10.0) |
150 + 379644.0 * std::pow (D, 10.0) |
149 + 2253373.0 * pow (D, 11.0) |
151 + 2253373.0 * std::pow (D, 11.0) |
150 + 13073811.0 * pow (D, 12.0) |
152 + 13073811.0 * std::pow (D, 12.0) |
151 + 75152755.0 * pow (D, 13.0) |
153 + 75152755.0 * std::pow (D, 13.0) |
152 + 428005675.0 * pow (D, 14.0) |
154 + 428005675.0 * std::pow (D, 14.0) |
153 ); |
155 ); |
154 } |
156 } |
155 else |
157 else |
156 { |
158 { |
157 NS_ASSERT (false); |
159 NS_ASSERT (false); |