Commit db9b8ef9 authored by Garnier Jean-Romain's avatar Garnier Jean-Romain
Browse files

Merge branch 'dev' into 'master'

Merge dev into master

See merge request garnier_jea/NOMA!6
parents f7639384 f0544ecc
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import Theorie_N_recepteurs as NOMATh
N = 3
Pmax = 1
sigma = 0.05
g = 1
it = 10000
P1 = [0., 0., 0., 0.05, 0.1, 0., 0.05, 0.1, 0.15, 0., 0.05, 0.1, 0.15, 0.2, 0., 0.05, 0.1, 0.15, 0.2, 0.25, 0., 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0., 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0., 0.05, 0.1, 0.15, 0.2, 0., 0.05, 0.1, 0.]
P2 = [0., 0.05, 0.1, 0.1, 0.1, 0.15, 0.15, 0.15, 0.15, 0.2, 0.2, 0.2, 0.2, 0.2, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.4, 0.4, 0.4, 0.4, 0.4, 0.45, 0.45, 0.45, 0.5]
BER3 = [0, 0, 0, 0, 0, 0, 0, 0.004, 0.045, 0, 0.0005, 0.035, 0.16, 0.24, 0, 0.01, 0.14, 0.23, 0.24, 0.25, 0, 0.075, 0.22, 0.25, 0.25, 0.25, 0.25, 0, 0.19, 0.245, 0.26, 0.25, 0.25, 0.26, 0.02, 0.25, 0.25, 0.255, 0.25, 0.05, 0.24, 0.25, 0.25]
BER2 = [0.5, 0.005, 0.0001, 0.05, 0.25, 0, 0.015, 0.1, 0.3, 0, 0.002, 0.07, 0.3, 0.5, 0, 0.01, 0.15, 0.29, 0.4, 0.5, 0, 0.075, 0.22, 0.27, 0.31, 0.37, 0.5, 0, 0.19, 0.245, 0.27, 0.28, 0.3, 0.3, 0.02, 0.25, 0.25, 0.255, 0.27, 0.05, 0.24, 0.25, 0.25]
BER1 = [0.5, 0.5, 0.5, 0.05, 0.25, 0.5, 0.023, 0.1, 0.3, 0.5, 0.011, 0.07, 0.3, 0.5, 0.5, 0.02, 0.15, 0.28, 0.31, 0.26, 0.5, 0.085, 0.21, 0.16, 0.07, 0.11, 0.26, 0.5, 0.22, 0.16, 0.03, 0.03, 0.04, 0.25, 0.5, 0.13, 0.03, 0.01, 0.02, 0.5, 0.06, 0.03, 0.5]
def main():
"""
Graph le BER théorique et le BER expérimental
"""
BERTotalList = []
BERTotalThList = []
BER3List = []
BER3ThList = []
BER2List = []
BER2ThList = []
BER1List = []
BER1ThList = []
for i in range(len(P1)):
p1 = P1[i]
p2 = P2[i]
p3 = Pmax - p2 - p1
ber3 = BER3[i]
ber2 = BER2[i]
ber1 = BER1[i]
ber1th, ber2th, ber3th = NOMATh.theorie(g, sigma, [p1, p2, p3], N)
BERTotalList.append(ber1 + ber2 + ber3)
BERTotalThList.append(ber1th + ber2th + ber3th)
BER3List.append(ber3)
BER3ThList.append(ber3th)
BER2List.append(ber2)
BER2ThList.append(ber2th)
BER1List.append(ber1)
BER1ThList.append(ber1th)
plt.figure()
ax = plt.axes(projection="3d")
ax.set_xlabel("P1")
ax.set_ylabel("P2")
ax.set_zlabel("Somme des BER")
ax.set_title("BER total à N={} utilisateurs en fonction des puissances avec Pmax = {}, g = {} et σ = {}".format(N, Pmax, g, sigma))
ax.plot(P1, P2, BERTotalThList, markerfacecolor="r", marker="o", markersize=5, linestyle="None")
ax.plot(P1, P2, BERTotalList, markerfacecolor="b", marker="x", markersize=5, linestyle="None")
plt.show(True)
plt.figure()
ax = plt.axes(projection="3d")
ax.set_xlabel("P1")
ax.set_ylabel("P2")
ax.set_zlabel("BER3")
ax.set_title("BER de l'utilisateur 3 à N={} utilisateurs en fonction des puissances avec Pmax = {}, g = {} et σ = {}".format(N, Pmax, g, sigma))
ax.plot(P1, P2, BER3List, markerfacecolor="r", marker="o", markersize=5, linestyle="None")
ax.plot(P1, P2, BER3ThList, markerfacecolor="b", marker="x", markersize=5, linestyle="None")
plt.show(True)
plt.figure()
ax = plt.axes(projection="3d")
ax.set_xlabel("P1")
ax.set_ylabel("P2")
ax.set_zlabel("BER2")
ax.set_title("BER de l'utilisateur 2 à N={} utilisateurs en fonction des puissances avec Pmax = {}, g = {} et σ = {}".format(N, Pmax, g, sigma))
ax.plot(P1, P2, BER2List, markerfacecolor="r", marker="o", markersize=5, linestyle="None")
ax.plot(P1, P2, BER2ThList, markerfacecolor="b", marker="x", markersize=5, linestyle="None")
plt.show(True)
plt.figure()
ax = plt.axes(projection="3d")
ax.set_xlabel("P1")
ax.set_ylabel("P2")
ax.set_zlabel("BER1")
ax.set_title("BER de l'utilisateur 1 à N={} utilisateurs en fonction des puissances avec Pmax = {}, g = {} et σ = {}".format(N, Pmax, g, sigma))
ax.plot(P1, P2, BER1List, markerfacecolor="r", marker="o", markersize=5, linestyle="None")
ax.plot(P1, P2, BER1ThList, markerfacecolor="b", marker="x", markersize=5, linestyle="None")
plt.show(True)
if __name__ == '__main__':
main()
......@@ -20,19 +20,28 @@
<type>int</type>
</param>
<check>$nusers &gt; 0</check>
<check>$bufferLength &gt; 0</check>
<!--
First n values are the expected values
First n values are the reference values
The last n values are what has been decoded
-->
<sink>
<name>in</name>
<name>in_ref</name>
<type>complex</type>
<nports>$nusers</nports>
</sink>
<sink>
<name>in_recv</name>
<type>complex</type>
<nports>(2 * $nusers)</nports>
<nports>$nusers</nports>
</sink>
<source>
<name>out</name>
<name>BER</name>
<type>float</type>
<nports>($nusers)</nports>
<nports>$nusers</nports>
</source>
</block>
......@@ -13,10 +13,12 @@
<type>int</type>
</param>
<check>$nusers &gt; 0</check>
<sink>
<name>in</name>
<name>P</name>
<type>float</type>
<nports>($nusers)</nports>
<nports>$nusers</nports>
</sink>
<sink>
......@@ -28,6 +30,6 @@
<source>
<name>out</name>
<type>complex</type>
<nports>($nusers)</nports>
<nports>$nusers</nports>
</source>
</block>
......@@ -25,9 +25,13 @@
<type>int</type>
</param>
<check>$nusers &gt; 0</check>
<check>$sampRate &gt; 0</check>
<check>$freq &gt; 0</check>
<source>
<name>out</name>
<type>complex</type>
<nports>($nusers)</nports>
<nports>$nusers</nports>
</source>
</block>
......@@ -17,6 +17,9 @@
<type>int</type>
</param>
<check>$phase_shift &gt; 0</check>
<check>$resamp_ratio &gt; 0</check>
<sink>
<name>in</name>
<type>complex</type>
......
......@@ -13,16 +13,18 @@
<type>int</type>
</param>
<check>$nusers &gt; 0</check>
<sink>
<name>in</name>
<name>P</name>
<type>float</type>
<nports>($nusers)</nports>
<nports>$nusers</nports>
</sink>
<sink>
<name>in</name>
<type>complex</type>
<nports>($nusers)</nports>
<nports>$nusers</nports>
</sink>
<source>
......
......@@ -32,6 +32,10 @@
<type>int</type>
</param>
<check>$sampRate &gt; 0</check>
<check>$freq &gt; 0</check>
<check>$procPerSymbol &lt;= ($sampRate / $freq)</check>
<sink>
<name>in</name>
<type>complex</type>
......
......@@ -20,9 +20,13 @@
<param>
<name>List of sync frames</name>
<key>syncFrames</key>
<value>[1, 1j, -1, -1j]</value>
<type>complex_vector</type>
</param>
<check>$sampRate &gt; 0</check>
<check>$freq &gt; 0</check>
<sink>
<name>in</name>
<type>complex</type>
......
......@@ -29,9 +29,16 @@ namespace gr {
namespace NOMA {
/*!
* \brief <+description of block+>
* \brief Compute the Binary Error Rate for N users when provided the expected and decoded results.
* \ingroup NOMA
*
* \details
* in[0...N-1] reference values\n
* in[N...2N-1] received values\n
* out BER\n
* \n
* in[0] is compared to in[N], in[1] to in[N+1] and so one.\n
*
*/
class NOMA_API BERCounter : virtual public gr::sync_block
{
......
......@@ -29,9 +29,13 @@ namespace gr {
namespace NOMA {
/*!
* \brief <+description of block+>
* \brief Decode N users NOMA symbol, expected input to use a QPSK constellation for each user.
* \ingroup NOMA
*
* \details
* in[0...N-1] Each user's power (in decreasing order of magnitude)\n
* in[N] The complex symbol to decode\n
* out[0...N-1] Each user's decoded symbol\n
*/
class NOMA_API decode_cc : virtual public gr::sync_block
{
......
......@@ -29,9 +29,11 @@ namespace gr {
namespace NOMA {
/*!
* \brief <+description of block+>
* \brief Generate a random complex at a given frequency.
* \ingroup NOMA
*
* \details
* freq corresponds to samp_rate / sps, with sps the number of samples per symbol to output.\n
*/
class NOMA_API random_source_c : virtual public gr::sync_block
{
......
......@@ -29,9 +29,12 @@ namespace gr {
namespace NOMA {
/*!
* \brief <+description of block+>
* \brief Keeps only 1 symbol out of resamp_ratio, dephased starting at phase_shift * resamp_ratio.
* \ingroup NOMA
*
* \details
* Allows the user to extract only meaningful values from a given set. The resamp_ratio is typically sps (number of samples per symbol).\n
* phase_shift helps choosing which value is kept. For example, if resamp_ratio=32 and phase_shift=0.5, then, every 32 values, only the 16th value is kepts (which probably corresponds to the max power).\n
*/
class NOMA_API resampler_cc : virtual public gr::block
{
......
......@@ -29,9 +29,15 @@ namespace gr {
namespace NOMA {
/*!
* \brief <+description of block+>
* \brief Create a signle symbol from multiple users' symbols using NOMA.
* \ingroup NOMA
*
* \details
* in[0...N-1] each user's power (in decreasing order of magnitude)\n
* in[N...2N-1] each user's symbol to transmit\n
* out the ponderated sum of users' symbols\n
* \n
* The output corresponds to in[0] * sqrt(in[N] / 2) + in[1] * sqrt(in[N+1] / 2) + ...\n
*/
class NOMA_API signalMerger : virtual public gr::sync_block
{
......
......@@ -29,9 +29,18 @@ namespace gr {
namespace NOMA {
/*!
* \brief <+description of block+>
* \brief Block which automatically corrects the phase and amplitude of received symbols.
* \ingroup NOMA
*
* \details
* This should be at the receiving end of a sync_frame_sender.\n
* This block uses an initial burst of known symbols to compute the average phase and amplitude difference, and corrects it for all the following symbols.\n
* It expects the initial known symbols (defined in the syncFrames vector of complex values) to be sent with a frequency of freq (where freq = sample_rate / sps).\n
* The goal of this block is to not drop any symbolNo symbol is dropped by the block (it just prepends some symbols at the start).
* Increasing procPerSymbol means that, for each known symbol, multiple values will be analyzed to compute the phase and amplitude difference. It is recommended to only increase this if the received symbols stay long enough at the optimal amplitude (i.e. the transition period is small).\n
* \n
* WARNING: The values in syncFrames MUST be != 0. Indeed, since this block is meant to be placed after an USRP source, it will initally be given noise by the antenna until the USRP source actually sends symbols. This means we have to find out which symbols are noise. This is done with a simple amplitude threshold on received values.\n
* TODO: Make the threashold modifiable in the block params. Discard only the first "zeros" (aka noise) received. Ignore zeros in syncFrames.\n
*/
class NOMA_API sync_frames_receiver : virtual public gr::block
{
......
......@@ -29,9 +29,16 @@ namespace gr {
namespace NOMA {
/*!
* \brief <+description of block+>
* \brief Block which initially sends reference symbols and, coupled with a sync_frams_receiver, corrects the phase and amplitude of received symbols.
* \ingroup NOMA
*
* \details
* This should be at the sending end of a sync_frame_sender.\n
* This block sends an initial burst of known symbols, later used in sync_frames_receiver to compute the average phase and amplitude difference, and correct it for all the following symbols.\n
* It sends the initial known symbols (defined in the syncFrames vector of complex values) with a frequency of freq (where freq = sample_rate / sps).\n
* After sending those symbols, it just acts as a passthrough block. No symbol is dropped by the block (it just prepends some symbols at the start).\n
* \n
* WARNING: The values in syncFrames MUST be != 0 (see sync_frames_receiver for details).\n
*/
class NOMA_API sync_frames_sender : virtual public gr::block
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment