Ejemplo n.º 1
0
def test_link_performance():
    # Apply link_performance to SISO QPSK and AWGN channel
    QPSK = QAMModem(4)

    def receiver(y, h, constellation):
        return QPSK.demodulate(y, 'hard')
    model = LinkModel(QPSK.modulate, SISOFlatChannel(fading_param=(1 + 0j, 0)), receiver,
                      QPSK.num_bits_symbol, QPSK.constellation, QPSK.Es)

    BERs = link_performance(model, range(0, 9, 2), 600e4, 600)
    desired = erfc(sqrt(10**(arange(0, 9, 2) / 10) / 2)) / 2
    assert_allclose(BERs, desired, rtol=0.25,
                    err_msg='Wrong performance for SISO QPSK and AWGN channel')

    # Apply link_performance to MIMO 16QAM and 4x4 Rayleigh channel
    QAM16 = QAMModem(16)
    RayleighChannel = MIMOFlatChannel(4, 4)
    RayleighChannel.uncorr_rayleigh_fading(complex)

    def receiver(y, h, constellation):
        return QAM16.demodulate(kbest(y, h, constellation, 16), 'hard')
    model = LinkModel(QAM16.modulate, RayleighChannel, receiver,
                      QAM16.num_bits_symbol, QAM16.constellation, QAM16.Es)
    SNRs = arange(0, 21, 5) + 10 * log10(QAM16.num_bits_symbol)

    BERs = link_performance(model, SNRs, 600e4, 600)
    desired = (2e-1, 1e-1, 3e-2, 2e-3, 4e-5)  # From reference
    assert_allclose(BERs, desired, rtol=1.25,
                    err_msg='Wrong performance for MIMO 16QAM and 4x4 Rayleigh channel')
Ejemplo n.º 2
0
def test_wifi80211_mimo_channel():
    seed(17121996)
    # Apply link_performance to MIMO 16QAM and 4x4 Rayleigh channel
    wifi80211 = Wifi80211(3)
    RayleighChannel = MIMOFlatChannel(4, 4)
    RayleighChannel.uncorr_rayleigh_fading(complex)
    modem = wifi80211.get_modem()

    def receiver(y, h, constellation, noise_var):
        return modem.demodulate(kbest(y, h, constellation, 16), 'hard')

    BERs = wifi80211.link_performance(RayleighChannel,
                                      arange(0, 21, 5) +
                                      10 * log10(modem.num_bits_symbol),
                                      10**4,
                                      600,
                                      receiver=receiver)[0]
    desired = (0.535, 0.508, 0.521, 0.554, 0.475)  # From previous test
    assert_allclose(
        BERs,
        desired,
        rtol=1.25,
        err_msg='Wrong performance for MIMO 16QAM and 4x4 Rayleigh channel')
Ejemplo n.º 3
0
    def do(self, nb_tx, nb_rx):
        # Set seed
        seed(17121996)

        def check_chan_gain(mod, chan):
            msg = choice(mod, self.msg_length)
            chan.propagate(msg)

            P_msg = signal_power(msg)
            P_unnoisy = signal_power(chan.unnoisy_output)

            assert_allclose(P_unnoisy, P_msg * chan.nb_tx, rtol=0.2,
                            err_msg='Channel add or remove energy')

        def expo_correlation(t, r):
            # Construct the exponent matrix
            expo_tx = fromiter((j - i for i in range(chan.nb_tx) for j in range(chan.nb_tx)), int, chan.nb_tx ** 2)
            expo_rx = fromiter((j - i for i in range(chan.nb_rx) for j in range(chan.nb_rx)), int, chan.nb_rx ** 2)

            # Reshape
            expo_tx = expo_tx.reshape(chan.nb_tx, chan.nb_tx)
            expo_rx = expo_rx.reshape(chan.nb_rx, chan.nb_rx)

            return t ** expo_tx, r ** expo_rx

        def check_correlation(chan, Rt, Rr):
            nb_ant = chan.nb_tx * chan.nb_rx
            Rdes = kron(Rt, Rr)
            H = chan.channel_gains
            Ract = zeros_like(Rdes)
            for i in range(len(H)):
                Ract += H[i].T.reshape(nb_ant, 1).dot(H[i].T.reshape(1, nb_ant).conj())
            Ract /= len(H)
            assert_allclose(Rdes, Ract, atol=0.05,
                            err_msg='Wrong correlation matrix')

        # Test value checking in constructor construction
        with assert_raises(ValueError):
            MIMOFlatChannel(nb_tx, nb_tx, 0, (ones((nb_tx, nb_tx)), ones((nb_tx, nb_tx)), ones((nb_rx, nb_rx))))

        chan = MIMOFlatChannel(nb_tx, nb_rx, 0)
        prod_nb = nb_tx * nb_rx

        # Test on real channel
        for mod in self.real_mods:
            # Test value checking after construction
            with assert_raises(ValueError):
                chan.fading_param = (ones((nb_tx, nb_tx)), ones((nb_tx, nb_tx)), ones((nb_rx, nb_rx)))

            # Test with Rayleigh fading
            chan.fading_param = (zeros((nb_rx, nb_tx)), identity(nb_tx), identity(nb_rx))
            check_chan_gain(mod, chan)

            # Test with rician fading
            mean = randn(nb_rx, nb_tx)
            mean *= sqrt(prod_nb * 0.75 / einsum('ij,ij->', absolute(mean), absolute(mean)))
            Rt = self.random_SDP_matrix(nb_tx) * sqrt(prod_nb) * 0.5
            Rr = self.random_SDP_matrix(nb_rx) * sqrt(prod_nb) * 0.5
            chan.fading_param = (mean, Rt, Rr)
            check_chan_gain(mod, chan)

            # Test helper functions
            chan.uncorr_rayleigh_fading(float)
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 0,
                            err_msg='Wrong k-factor with uncorrelated Rayleigh fading')

            mean = randn(nb_rx, nb_tx)
            chan.uncorr_rician_fading(mean, 10)
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 10,
                            err_msg='Wrong k-factor with uncorrelated rician fading')

        # Test on complex channel
        for mod in self.all_mods:
            # Test value checking after construction
            with assert_raises(ValueError):
                chan.fading_param = (ones((nb_tx, nb_tx)), ones((nb_tx, nb_tx)), ones((nb_rx, nb_rx)))

            # Test with Rayleigh fading
            chan.fading_param = (zeros((nb_rx, nb_tx), complex), identity(nb_tx), identity(nb_rx))
            check_chan_gain(mod, chan)
            assert_allclose(chan.channel_gains.mean(), 0, atol=1e-2,
                            err_msg='Wrong channel mean with complex channel')
            assert_allclose(chan.channel_gains.var(), 1, atol=5e-2,
                            err_msg='Wrong channel variance with complex channel')

            # Test with rician fading
            mean = randn(nb_rx, nb_tx) + 1j * randn(nb_rx, nb_tx)
            mean *= sqrt(prod_nb * 0.75 / einsum('ij,ij->', absolute(mean), absolute(mean)))
            Rt = self.random_SDP_matrix(nb_tx) * sqrt(prod_nb) * 0.5
            Rr = self.random_SDP_matrix(nb_rx) * sqrt(prod_nb) * 0.5
            chan.fading_param = (mean, Rt, Rr)
            check_chan_gain(mod, chan)

            assert_allclose(chan.channel_gains.mean(0).real, mean.real, atol=0.1,
                            err_msg='Wrong channel mean with complex channel')
            assert_allclose(chan.channel_gains.mean(0).imag, mean.imag, atol=0.1,
                            err_msg='Wrong channel mean with complex channel')

            # Test helper functions
            chan.uncorr_rayleigh_fading(complex)
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 0,
                            err_msg='Wrong k-factor with uncorrelated Rayleigh fading')

            mean = randn(nb_rx, nb_tx) + randn(nb_rx, nb_tx) * 1j
            chan.uncorr_rician_fading(mean, 10)
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 10,
                            err_msg='Wrong k-factor with uncorrelated rician fading')

            chan.expo_corr_rayleigh_fading(exp(-0.2j * pi), exp(-0.1j * pi))
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 0,
                            err_msg='Wrong k-factor with correlated Rayleigh fading')
            Rt, Rr = expo_correlation(exp(-0.2j * pi), exp(-0.1j * pi))
            check_correlation(chan, Rt, Rr)

            mean = randn(nb_rx, nb_tx) + randn(nb_rx, nb_tx) * 1j
            chan.expo_corr_rician_fading(mean, 10, exp(-0.1j * pi), exp(-0.2j * pi))
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 10,
                            err_msg='Wrong k-factor with correlated rician fading')

            # Test with beta > 0
            chan.expo_corr_rayleigh_fading(exp(-0.2j * pi), exp(-0.1j * pi), 1, 0.5)
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 0,
                            err_msg='Wrong k-factor with correlated Rayleigh fading')

            mean = randn(nb_rx, nb_tx) + randn(nb_rx, nb_tx) * 1j
            chan.expo_corr_rician_fading(mean, 5, exp(-0.1j * pi), exp(-0.2j * pi), 3, 2)
            check_chan_gain(mod, chan)
            assert_allclose(chan.k_factor, 5,
                            err_msg='Wrong k-factor with correlated rician fading')
Ejemplo n.º 4
0
def test_link_performance():
    # Set seed
    seed(8071996)
    ######################################
    # Build models & desired solutions
    ######################################
    models = []
    desired_bers = []
    snr_range = []
    labels = []
    rtols = []
    code_rates = []

    # SISO QPSK and AWGN channel
    QPSK = QAMModem(4)

    def receiver(y, h, constellation, noise_var):
        return QPSK.demodulate(y, 'hard')

    models.append(
        LinkModel(QPSK.modulate, SISOFlatChannel(fading_param=(1 + 0j, 0)),
                  receiver, QPSK.num_bits_symbol, QPSK.constellation, QPSK.Es))
    snr_range.append(arange(0, 9, 2))
    desired_bers.append(erfc(sqrt(10**(snr_range[-1] / 10) / 2)) / 2)
    labels.append('SISO QPSK and AWGN channel')
    rtols.append(.25)
    code_rates.append(1)

    # MIMO 16QAM, 4x4 Rayleigh channel and hard-output K-Best
    QAM16 = QAMModem(16)
    RayleighChannel = MIMOFlatChannel(4, 4)
    RayleighChannel.uncorr_rayleigh_fading(complex)

    def receiver(y, h, constellation, noise_var):
        return QAM16.demodulate(kbest(y, h, constellation, 16), 'hard')

    models.append(
        LinkModel(QAM16.modulate, RayleighChannel, receiver,
                  QAM16.num_bits_symbol, QAM16.constellation, QAM16.Es))
    snr_range.append(arange(0, 21, 5) + 10 * log10(QAM16.num_bits_symbol))
    desired_bers.append((2e-1, 1e-1, 3e-2, 2e-3, 4e-5))  # From reference
    labels.append('MIMO 16QAM, 4x4 Rayleigh channel and hard-output K-Best')
    rtols.append(1.25)
    code_rates.append(1)

    # MIMO 16QAM, 4x4 Rayleigh channel and soft-output best-first
    QAM16 = QAMModem(16)
    RayleighChannel = MIMOFlatChannel(4, 4)
    RayleighChannel.uncorr_rayleigh_fading(complex)
    ldpc_params = get_ldpc_code_params(
        'commpy/channelcoding/designs/ldpc/wimax/1440.720.txt', True)

    def modulate(bits):
        return QAM16.modulate(
            triang_ldpc_systematic_encode(bits, ldpc_params,
                                          False).reshape(-1, order='F'))

    def decoder(llrs):
        return ldpc_bp_decode(llrs, ldpc_params, 'MSA',
                              15)[0][:720].reshape(-1, order='F')

    def demode(symbs):
        return QAM16.demodulate(symbs, 'hard')

    def receiver(y, h, constellation, noise_var):
        return best_first_detector(y, h, constellation, (1, 3, 5), noise_var,
                                   demode, 500)

    models.append(
        LinkModel(modulate, RayleighChannel, receiver, QAM16.num_bits_symbol,
                  QAM16.constellation, QAM16.Es, decoder, 0.5))
    snr_range.append(arange(17, 20, 1))
    desired_bers.append((1.7e-1, 1e-1, 2.5e-3))  # From reference
    labels.append(
        'MIMO 16QAM, 4x4 Rayleigh channel and soft-output best-first')
    rtols.append(2)
    code_rates.append(.5)

    ######################################
    # Make tests
    ######################################

    for test in range(len(models)):
        BERs = link_performance(models[test], snr_range[test], 5e5, 200, 720,
                                models[test].rate)
        assert_allclose(BERs,
                        desired_bers[test],
                        rtol=rtols[test],
                        err_msg='Wrong performance for ' + labels[test])
        full_metrics = models[test].link_performance_full_metrics(
            snr_range[test], 2500, 200, 720, models[test].rate)
        assert_allclose(full_metrics[0],
                        desired_bers[test],
                        rtol=rtols[test],
                        err_msg='Wrong performance for ' + labels[test])