def test_calculating_the_chordal_distance(self):
        expected_chord_dist = np.array([0.473867859572])

        # Test calcChordalDistance
        np.testing.assert_array_almost_equal(metrics.calc_chordal_distance(self.A, self.B), expected_chord_dist)

        # Test calcChordalDistance2
        np.testing.assert_array_almost_equal(metrics.calc_chordal_distance_2(self.A, self.B), expected_chord_dist)

        # Test
        principal_angles = metrics.calc_principal_angles(self.A, self.B)
        np.testing.assert_array_almost_equal(
            metrics.calc_chordal_distance_from_principal_angles(principal_angles), expected_chord_dist
        )

        # xxxxxxxxxx Now let's test with complex values xxxxxxxxxxxxxxxxxxx
        A = randn_c(3, 2)
        B = randn_c(3, 2)
        principal_angles2 = metrics.calc_principal_angles(A, B)
        dist1 = metrics.calc_chordal_distance(A, B)
        dist2 = metrics.calc_chordal_distance_2(A, B)
        dist3 = metrics.calc_chordal_distance_from_principal_angles(principal_angles2)

        self.assertAlmostEqual(dist1, dist2)
        self.assertAlmostEqual(dist3, dist2)
Example #2
0
    def test_decode(self):
        data = np.r_[0:15]

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Test with an identity channel
        channel = np.eye(3)
        self.blast_object.set_channel_matrix(channel)
        encoded_data = self.blast_object.encode(data)
        decoded_data1 = self.blast_object.decode(encoded_data)
        np.testing.assert_array_almost_equal(decoded_data1, data)

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Test with a random channel and a zero-force filter
        self.blast_object.set_noise_var(None)  # This should use the ZF filter
        channel = randn_c(4, 3)  # 3 transmitt antennas and 4 receive antennas
        self.blast_object.set_channel_matrix(channel)
        received_data2 = np.dot(channel, encoded_data)
        decoded_data2 = self.blast_object.decode(received_data2)
        np.testing.assert_array_almost_equal(decoded_data2, data)

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Test with a random channel and a MMSE filter
        self.blast_object.set_noise_var(0.00000001)
        channel = randn_c(4, 3)  # 3 transmitt antennas and 4 receive antennas
        self.blast_object.set_channel_matrix(channel)
        received_data3 = np.dot(channel, encoded_data)
        decoded_data3 = self.blast_object.decode(received_data3)
        np.testing.assert_array_almost_equal(decoded_data3.round(7), data)
    def test_calculating_the_chordal_distance(self):
        expected_chord_dist = 0.473867859572

        # Test calcChordalDistance
        self.assertAlmostEqual(metrics.calc_chordal_distance(self.A, self.B),
                               expected_chord_dist)

        # Test calcChordalDistance2
        self.assertAlmostEqual(metrics.calc_chordal_distance_2(self.A, self.B),
                               expected_chord_dist)

        # Test
        principal_angles = metrics.calc_principal_angles(self.A, self.B)
        self.assertAlmostEqual(
            metrics.calc_chordal_distance_from_principal_angles(
                principal_angles), expected_chord_dist)

        # xxxxxxxxxx Now let's test with complex values xxxxxxxxxxxxxxxxxxx
        A = randn_c(3, 2)
        B = randn_c(3, 2)
        principal_angles2 = metrics.calc_principal_angles(A, B)
        dist1 = metrics.calc_chordal_distance(A, B)
        dist2 = metrics.calc_chordal_distance_2(A, B)
        dist3 = metrics.calc_chordal_distance_from_principal_angles(
            principal_angles2)

        self.assertAlmostEqual(dist1, dist2)
        self.assertAlmostEqual(dist3, dist2)
Example #4
0
    def test_encode(self):
        data = np.r_[0:15]

        # xxxxxxxxxx test the case with Ntx=2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        Nt = 2
        channel = randn_c(Nt)
        self.mrt_object.set_channel_matrix(channel)

        data_aux = data.reshape(1, data.size)  # Useful for broadcasting
        ":type: np.ndarray"
        W = np.exp(-1j * np.angle(channel)).reshape(Nt, 1) / math.sqrt(Nt)
        ":type: np.ndarray"

        encoded_data = self.mrt_object.encode(data)

        expected_encoded_data = W * data_aux
        np.testing.assert_array_almost_equal(expected_encoded_data,
                                             encoded_data)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx test the case with Ntx=4 xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        Nt = 4
        channel = randn_c(Nt)
        self.mrt_object.set_channel_matrix(channel)

        data_aux = data.reshape(1, data.size)  # Useful for broadcasting
        ":type: np.ndarray"

        encoded_data = self.mrt_object.encode(data)
        W = np.exp(-1j * np.angle(channel)).reshape(Nt, 1)
        ":type: np.ndarray"

        expected_encoded_data = (1. / math.sqrt(Nt)) * W * data_aux
        np.testing.assert_array_almost_equal(expected_encoded_data,
                                             encoded_data)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Test the case where the channel is 2D xxxxxxxxxxxxxxxx
        # Note tha in this case even though the channel is a 2D numpy array
        # the size of the first dimension (receive antennas) must be equal
        # to 1.
        Nt = 4
        channel2 = randn_c(1, Nt)
        self.mrt_object.set_channel_matrix(channel2)

        data_aux = data.reshape(1, data.size)  # Useful for broadcasting
        ":type: np.ndarray"

        encoded_data = self.mrt_object.encode(data)
        W = np.exp(-1j * np.angle(channel2)).reshape(Nt, 1)
        ":type: np.ndarray"

        expected_encoded_data = (1. / math.sqrt(Nt)) * W * data_aux
        np.testing.assert_array_almost_equal(expected_encoded_data,
                                             encoded_data)
Example #5
0
    def test_set_channel_matrix(self):
        self.alamouti_object.set_channel_matrix(randn_c(2))
        self.assertEqual(self.alamouti_object.Nt, 2)
        self.assertEqual(self.alamouti_object.Nr, 1)

        self.alamouti_object.set_channel_matrix(randn_c(4, 2))
        self.assertEqual(self.alamouti_object.Nt, 2)
        self.assertEqual(self.alamouti_object.Nr, 4)

        with self.assertRaises(ValueError):
            self.alamouti_object.set_channel_matrix(randn_c(4, 3))
Example #6
0
    def test_calc_receive_filter(self):
        Pu = self.Pu
        noise_var = self.noise_var
        num_users = self.num_users
        # num_antennas = self.num_antennas
        channel = randn_c(self.iNr, self.iNt)

        (newH,
         _) = blockdiagonalization.block_diagonalize(channel, num_users, Pu,
                                                     noise_var)

        # W_bd is a block diagonal matrix, where each "small block" is the
        # receive filter of one user.
        W_bd = blockdiagonalization.calc_receive_filter(newH)

        np.testing.assert_array_almost_equal(np.dot(W_bd, newH),
                                             np.eye(self.iNt))

        # Retest for each individual user
        W0 = W_bd[0:2, 0:2]
        newH0 = newH[0:2, 0:2]

        np.testing.assert_array_almost_equal(np.dot(W0, newH0),
                                             np.eye(self.iNt // 3))
        W1 = W_bd[2:4, 2:4]
        newH1 = newH[2:4, 2:4]
        np.testing.assert_array_almost_equal(np.dot(W1, newH1),
                                             np.eye(self.iNt // 3))
        W2 = W_bd[4:, 4:]
        newH2 = newH[4:, 4:]
        np.testing.assert_array_almost_equal(np.dot(W2, newH2),
                                             np.eye(self.iNt // 3))
Example #7
0
    def test_perform_normalized_waterfilling_power_scaling(self):
        channel = randn_c(self.iNr, self.iNt)
        (Ms_bad, Sigma) = self.BD._calc_BD_matrix_no_power_scaling(channel)

        Ms_good = self.BD._perform_normalized_waterfilling_power_scaling(
            Ms_bad, Sigma)
        # Ms_good = self.BD._perform_global_waterfilling_power_scaling(
        #     Ms_bad, Sigma)

        # xxxxx Now lets test the power restriction xxxxxxxxxxxxxxxxxxxxxxx
        # Total power restriction
        total_power = self.Pu * self.num_users
        self.assertGreaterEqual(total_power,
                                np.linalg.norm(Ms_good, 'fro') ** 2)

        # xxxxx Test the Individual power restriction of each user xxxxxxxx
        # Cummulated number of transmit antennas
        cum_Nt = np.cumsum(
            np.hstack([0,
                       np.ones(self.num_users, dtype=int) * self.num_antenas]))

        individual_powers = []
        for i in range(self.num_users):
            # Most likelly only one base station (the one with the worst
            # channel) will employ a precoder with total power of `Pu`,
            # while the other base stations will use less power.
            individual_powers.append(
                np.linalg.norm(
                    Ms_good[:, cum_Nt[i]:cum_Nt[i] + self.num_antenas], 'fro'
                ) ** 2)
            # 1e-12 is included to avoid false test fails due to small
            # precision errors
            tol = 1e-12
            self.assertGreaterEqual(self.Pu + tol,
                                    individual_powers[-1])
Example #8
0
    def test_perform_global_waterfilling_power_scaling(self):
        channel = randn_c(self.iNr, self.iNt)
        (Ms_bad, Sigma) = self.BD._calc_BD_matrix_no_power_scaling(channel)

        Ms_good = self.BD._perform_global_waterfilling_power_scaling(
            Ms_bad, Sigma)

        # Ms_good must have the same shape as Ms_bad
        np.testing.assert_array_equal(Ms_bad.shape, Ms_good.shape)

        # The total available power is equal to the power per user times
        # the number of users
        total_power = self.Pu * self.num_users

        # The square of the Frobenius norm of Ms_good must be equal to the
        # total available power
        self.assertAlmostEqual(np.linalg.norm(Ms_good, 'fro') ** 2,
                               total_power)

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Ms_good must still be able to block diagonalize the channel
        A = np.ones([self.iNrk, self.iNtk])
        mask = block_diag(A, A, A)
        newH = np.dot(channel, Ms_good)

        # With the mask we can create a masked array of the block
        # diagonalized channel
        masked_newH = np.ma.masked_array(newH, mask)
        # Now we can sum all elements of this masked array (which
        # effectively means all elements outside the block diagonal) and
        # see if it is close to zero.
        self.assertAlmostEqual(0., np.abs(masked_newH).sum())
Example #9
0
    def test_calc_BD_matrix_no_power_scaling(self):
        channel = randn_c(self.iNr, self.iNt)
        (Ms_bad, _) = self.BD._calc_BD_matrix_no_power_scaling(channel)

        newH = np.dot(channel, Ms_bad)

        # Because Ms_bad does not have any power scaling and each column of
        # it comes is a singular vector calculated with the SVD, then the
        # square of its Frobenius norm is equal to its dimension.
        self.assertAlmostEqual(np.linalg.norm(Ms_bad, 'fro') ** 2,
                               Ms_bad.shape[0])

        # Now let's test if newH is really a block diagonal matrix.
        # First we create a 'mask'
        A = np.ones([self.iNrk, self.iNtk])
        mask = block_diag(A, A, A)

        # With the mask we can create a masked array of the block
        # diagonalized channel which effectively removes the elements in
        # the block diagonal
        masked_newH = np.ma.masked_array(newH, mask)

        # If we sum all the elements in the masked channel (the mask
        # removes the elements in the block diagonal) it should be equal to
        # zero
        self.assertAlmostEqual(0., np.abs(masked_newH).sum())
Example #10
0
    def test_calc_receive_filter(self):
        Pu = self.Pu
        noise_var = self.noise_var
        num_users = self.num_users
        # num_antenas = self.num_antenas
        channel = randn_c(self.iNr, self.iNt)

        (newH, _) = blockdiagonalization.block_diagonalize(
            channel, num_users, Pu, noise_var)

        # W_bd is a block diagonal matrix, where each "small block" is the
        # receive filter of one user.
        W_bd = blockdiagonalization.calc_receive_filter(newH)

        np.testing.assert_array_almost_equal(np.dot(W_bd, newH),
                                             np.eye(np.sum(self.iNt)))

        # Retest for each individual user
        W0 = W_bd[0:2, 0:2]
        newH0 = newH[0:2, 0:2]
        np.testing.assert_array_almost_equal(np.dot(W0, newH0),
                                             np.eye(self.iNt/3))
        W1 = W_bd[2:4, 2:4]
        newH1 = newH[2:4, 2:4]
        np.testing.assert_array_almost_equal(np.dot(W1, newH1),
                                             np.eye(self.iNt/3))
        W2 = W_bd[4:, 4:]
        newH2 = newH[4:, 4:]
        np.testing.assert_array_almost_equal(np.dot(W2, newH2),
                                             np.eye(self.iNt/3))
Example #11
0
    def test_init(self):
        channel1 = randn_c(3)
        mrt_object1 = MRT(channel1)
        self.assertEqual(3, mrt_object1.Nt)
        self.assertEqual(1, mrt_object1.Nr)

        channel2 = randn_c(1, 3)
        mrt_object2 = MRT(channel2)
        self.assertEqual(3, mrt_object2.Nt)
        self.assertEqual(1, mrt_object2.Nr)

        channel3 = randn_c(2, 3)
        # Number of receive antennas must be exact 1. Since channel3 has 2
        # receive antennas, an exception should be raised
        with self.assertRaises(ValueError):
            MRT(channel3)
Example #12
0
    def test_encode(self):
        # xxxxxxxxxx test the case with Ntx=2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        Nt = 2
        Nr = 2
        data = np.r_[0:15*Nt]

        channel = randn_c(Nr, Nt)
        self.gmdmimo_object.set_channel_matrix(channel)

        encoded_data = self.gmdmimo_object.encode(data)

        # data_aux = data.reshape(Nt, -1)
        U, S, V_H = np.linalg.svd(channel)
        _, _, P = gmd(U, S, V_H)
        W = P / math.sqrt(Nt)

        expected_encoded_data = W.dot(data.reshape(Nr, -1))
        np.testing.assert_array_almost_equal(
            expected_encoded_data, encoded_data)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Test if an exception is raised for wrong size xxxxxxxxxxxxx
        # The exception is raised if the input array size is not a multiple
        # of the number of transmit antennas
        data2 = np.r_[0:15*Nt+1]
        with self.assertRaises(ValueError):
            self.gmdmimo_object.encode(data2)
    def test_modulate_and_demodulate(self):
        awgn_noise = randn_c(20,) * 1e-2

        # xxxxxxxxxx Test for 4-QAM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        input_data = np.random.random_integers(0, 4 - 1, 20)
        modulated_data = self.qam_obj.modulate(input_data)
        demodulated_data = self.qam_obj.demodulate(modulated_data + awgn_noise)
        np.testing.assert_array_equal(input_data, demodulated_data)

        # xxxxxxxxxx Test for 16-QAM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        input_data2 = np.random.random_integers(0, 16 - 1, 20)
        modulated_data2 = self.qam_obj2.modulate(input_data2)
        demodulated_data2 = self.qam_obj2.demodulate(modulated_data2 + awgn_noise)
        np.testing.assert_array_equal(input_data2, demodulated_data2)

        # xxxxxxxxxx Test for 64-QAM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        input_data3 = np.random.random_integers(0, 64 - 1, 20)
        modulated_data3 = self.qam_obj3.modulate(input_data3)
        demodulated_data3 = self.qam_obj3.demodulate(modulated_data3 + awgn_noise)
        np.testing.assert_array_equal(input_data3, demodulated_data3)

        # Test if an exception is raised for invalid arguments
        with self.assertRaises(ValueError):
            self.qam_obj.modulate(4)

        with self.assertRaises(ValueError):
            self.qam_obj2.modulate(16)

        with self.assertRaises(ValueError):
            self.qam_obj3.modulate(65)
Example #14
0
    def test_decode(self):
        Nt = 4

        # xxxxxxxxxx test the case with a single receive antenna xxxxxxxxxx
        channel = randn_c(Nt)
        self.mrt_object.set_channel_matrix(channel)

        data = np.r_[0:15]
        encoded_data = self.mrt_object.encode(data)

        # Add '0.1' as a noise term
        received_data = channel.dot(encoded_data) + 0.0001
        decoded_data = self.mrt_object.decode(received_data)

        self.assertEqual(len(decoded_data.shape), 1)
        np.testing.assert_array_almost_equal(decoded_data, data, decimal=4)

        # Now we are explicitting changing the shape of the channel
        # variable to include the first dimension corresponding to a single
        # receive antenna
        channel.shape = (1, Nt)
        self.mrt_object.set_channel_matrix(channel)
        # The encoded data should be the same
        encoded_data = self.mrt_object.encode(data)

        # Add '0.1' as a noise term
        received_data = channel.dot(encoded_data) + 0.0001
        decoded_data = self.mrt_object.decode(received_data)

        self.assertEqual(len(decoded_data.shape), 1)
        np.testing.assert_array_almost_equal(decoded_data, data, decimal=4)
    def test_modulate_and_demodulate(self):
        awgn_noise = randn_c(20, ) * 1e-2

        # xxxxxxxxxx Test for 4-QAM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        input_data = np.random.randint(0, 4, 20)
        modulated_data = self.qam_obj.modulate(input_data)
        demodulated_data = self.qam_obj.demodulate(modulated_data + awgn_noise)
        np.testing.assert_array_equal(input_data, demodulated_data)

        # xxxxxxxxxx Test for 16-QAM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        input_data2 = np.random.randint(0, 16, 20)
        modulated_data2 = self.qam_obj2.modulate(input_data2)
        demodulated_data2 = self.qam_obj2.demodulate(modulated_data2 +
                                                     awgn_noise)
        np.testing.assert_array_equal(input_data2, demodulated_data2)

        # xxxxxxxxxx Test for 64-QAM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        input_data3 = np.random.randint(0, 64, 20)
        modulated_data3 = self.qam_obj3.modulate(input_data3)
        demodulated_data3 = self.qam_obj3.demodulate(modulated_data3 +
                                                     awgn_noise)
        np.testing.assert_array_equal(input_data3, demodulated_data3)

        # Test if an exception is raised for invalid arguments
        with self.assertRaises(ValueError):
            self.qam_obj.modulate(4)

        with self.assertRaises(ValueError):
            self.qam_obj2.modulate(16)

        with self.assertRaises(ValueError):
            self.qam_obj3.modulate(65)
Example #16
0
def simulate_and_compute_Rxx_U0(M, N, SNR, beam_sep):
    """
    Simulate and generate Rxx and U0 considering that three wavefronts were
    sent.

    M : int
    N : int
    SNR : float
    beam_sep : float
        Normalized beamwidth separation between the wavefronts. This separation
        is normalized by the beamwidth.
    """
    qpsk = modulators.QPSK()

    d = 3  # Number of inpinging waves
    mu_b = 2 * np.pi / M
    mu = np.array([-beam_sep * mu_b, 0, beam_sep * mu_b])  # Standard beamwidth

    data = np.random.randint(4, size=(d, N))
    modulated_data = qpsk.modulate(data) / sqrt(d)
    noise_power = 1. / dB2Linear(SNR)
    noise = sqrt(noise_power) * randn_c(M, N)
    steering_vec = calc_a_phi_vect(M, mu)
    received_data = steering_vec @ modulated_data + noise

    # Covariance matrix of the received Data
    Rxx = received_data @ received_data.T.conj()
    U, S, V_H = np.linalg.svd(Rxx)
    U0 = U[:, d:]

    return Rxx, U0
Example #17
0
    def test_calc_BD_matrix_no_power_scaling(self):
        channel = randn_c(self.iNr, self.iNt)
        (Ms_bad, _) = self.BD._calc_BD_matrix_no_power_scaling(channel)

        newH = np.dot(channel, Ms_bad)

        # Because Ms_bad does not have any power scaling and each column of
        # it comes is a singular vector calculated with the SVD, then the
        # square of its Frobenius norm is equal to its dimension.
        self.assertAlmostEqual(
            np.linalg.norm(Ms_bad, 'fro')**2, Ms_bad.shape[0])

        # Now let's test if newH is really a block diagonal matrix.
        # First we create a 'mask'
        A = np.ones([self.iNrk, self.iNtk])
        mask = block_diag(A, A, A)

        # With the mask we can create a masked array of the block
        # diagonalized channel which effectively removes the elements in
        # the block diagonal
        masked_newH = np.ma.masked_array(newH, mask)

        # If we sum all the elements in the masked channel (the mask
        # removes the elements in the block diagonal) it should be equal to
        # zero
        self.assertAlmostEqual(0., np.abs(masked_newH).sum())
Example #18
0
    def test_perform_global_waterfilling_power_scaling(self):
        channel = randn_c(self.iNr, self.iNt)
        (Ms_bad, Sigma) = self.BD._calc_BD_matrix_no_power_scaling(channel)

        Ms_good = self.BD._perform_global_waterfilling_power_scaling(
            Ms_bad, Sigma)

        # Ms_good must have the same shape as Ms_bad
        np.testing.assert_array_equal(Ms_bad.shape, Ms_good.shape)

        # The total available power is equal to the power per user times
        # the number of users
        total_power = self.Pu * self.num_users

        # The square of the Frobenius norm of Ms_good must be equal to the
        # total available power
        self.assertAlmostEqual(np.linalg.norm(Ms_good, 'fro')**2, total_power)

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Ms_good must still be able to block diagonalize the channel
        A = np.ones([self.iNrk, self.iNtk])
        mask = block_diag(A, A, A)
        newH = np.dot(channel, Ms_good)

        # With the mask we can create a masked array of the block
        # diagonalized channel
        masked_newH = np.ma.masked_array(newH, mask)
        # Now we can sum all elements of this masked array (which
        # effectively means all elements outside the block diagonal) and
        # see if it is close to zero.
        self.assertAlmostEqual(0., np.abs(masked_newH).sum())
Example #19
0
    def test_perform_normalized_waterfilling_power_scaling(self):
        channel = randn_c(self.iNr, self.iNt)
        (Ms_bad, Sigma) = self.BD._calc_BD_matrix_no_power_scaling(channel)

        Ms_good = self.BD._perform_normalized_waterfilling_power_scaling(
            Ms_bad, Sigma)
        # Ms_good = self.BD._perform_global_waterfilling_power_scaling(
        #     Ms_bad, Sigma)

        # xxxxx Now lets test the power restriction xxxxxxxxxxxxxxxxxxxxxxx
        # Total power restriction
        total_power = self.Pu * self.num_users
        self.assertGreaterEqual(total_power, np.linalg.norm(Ms_good, 'fro')**2)

        # xxxxx Test the Individual power restriction of each user xxxxxxxx
        # accumulated number of transmit antennas
        cum_Nt = np.cumsum(
            np.hstack(
                [0, np.ones(self.num_users, dtype=int) * self.num_antennas]))

        individual_powers = []
        for i in range(self.num_users):
            # Most likely only one base station (the one with the worst
            # channel) will employ a precoder with total power of `Pu`,
            # while the other base stations will use less power.
            individual_powers.append(
                np.linalg.norm(
                    Ms_good[:, cum_Nt[i]:cum_Nt[i] + self.num_antennas],
                    'fro')**2)
            # 1e-12 is included to avoid false test fails due to small
            # precision errors
            tol = 1e-12
            self.assertGreaterEqual(self.Pu + tol, individual_powers[-1])
Example #20
0
    def test_encode(self):
        data = np.r_[0:15]

        # xxxxxxxxxx test the case with Ntx=2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        Nt = 2
        channel = randn_c(Nt)
        self.mrt_object.set_channel_matrix(channel)

        data_aux = data.reshape(1, data.size)  # Useful for broadcasting
        W = np.exp(-1j * np.angle(channel)).reshape(Nt, 1) / math.sqrt(Nt)
        encoded_data = self.mrt_object.encode(data)

        expected_encoded_data = W * data_aux
        np.testing.assert_array_almost_equal(expected_encoded_data,
                                             encoded_data)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx test the case with Ntx=4 xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        Nt = 4
        channel = randn_c(Nt)
        self.mrt_object.set_channel_matrix(channel)

        data_aux = data.reshape(1, data.size)  # Useful for broadcasting
        encoded_data = self.mrt_object.encode(data)
        W = np.exp(-1j * np.angle(channel)).reshape(Nt, 1)

        expected_encoded_data = (1. / math.sqrt(Nt)) * W * data_aux
        np.testing.assert_array_almost_equal(expected_encoded_data,
                                             encoded_data)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Test the case where the channel is 2D xxxxxxxxxxxxxxxx
        # Note tha in this case even though the channel is a 2D numpy array
        # the size of the first dimension (receive antennas) must be equal
        # to 1.
        Nt = 4
        channel2 = randn_c(1, Nt)
        self.mrt_object.set_channel_matrix(channel2)

        data_aux = data.reshape(1, data.size)  # Useful for broadcasting
        encoded_data = self.mrt_object.encode(data)
        W = np.exp(-1j * np.angle(channel2)).reshape(Nt, 1)

        expected_encoded_data = (1. / math.sqrt(Nt)) * W * data_aux
        np.testing.assert_array_almost_equal(expected_encoded_data,
                                             encoded_data)
Example #21
0
    def test_calc_receive_filter(self):
        # Equivalent channel without including stream reduction
        Heq_k = randn_c(3, 3)
        Re_k = randn_c(3, 2)
        Re_k = np.dot(Re_k, Re_k.transpose().conjugate())

        P1 = blockdiagonalization._calc_stream_reduction_matrix(Re_k, 1)
        P2 = blockdiagonalization._calc_stream_reduction_matrix(Re_k, 2)
        P3 = blockdiagonalization._calc_stream_reduction_matrix(Re_k, 3)

        # Equivalent channels with the stream reduction
        Heq_k_P1 = np.dot(Heq_k, P1)
        Heq_k_P2 = np.dot(Heq_k, P2)
        Heq_k_P3 = np.dot(Heq_k, P3)

        W1 = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k_P1, P1)
        W2 = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k_P2, P2)
        W3 = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k_P3, P3)
        # Note that since P3 is actually including all streams, then the
        # performance is the same as if we don't reduce streams. However W3
        # and W_full are different matrices, since W3 has to compensate the
        # right multiplication of the equivalent channel by P3 and W_full
        # does not. The performance is the same because no energy is lost
        # due to stream reduction and the Frobenius norms of W3 and W_full
        # are equal.
        W_full = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k)

        np.testing.assert_array_almost_equal(np.dot(W1, np.dot(Heq_k, P1)),
                                             np.eye(1))
        np.testing.assert_array_almost_equal(np.dot(W2, np.dot(Heq_k, P2)),
                                             np.eye(2))
        np.testing.assert_array_almost_equal(np.dot(W3, np.dot(Heq_k, P3)),
                                             np.eye(3))
        np.testing.assert_array_almost_equal(np.dot(W_full, Heq_k),
                                             np.eye(3))

        overbar_P2 = calcProjectionMatrix(P2)
        expected_W2 = np.dot(
            np.linalg.pinv(np.dot(overbar_P2, np.dot(Heq_k, P2))),
            overbar_P2)
        np.testing.assert_array_almost_equal(expected_W2, W2)
Example #22
0
 def test_decode(self):
     data = np.r_[0:16] + np.r_[0:16] * 1j
     encoded_data = self.alamouti_object.encode(data)
     # We will test the deconding with a random channel
     channel = randn_c(3, 2)
     self.alamouti_object.set_channel_matrix(channel)
     received_data = np.dot(channel, encoded_data)
     decoded_data = self.alamouti_object.decode(received_data)
     np.testing.assert_array_almost_equal(decoded_data, data)
Example #23
0
    def test_calc_receive_filter(self):
        # Equivalent channel without including stream reduction
        Heq_k = randn_c(3, 3)
        Re_k = randn_c(3, 2)
        Re_k = np.dot(Re_k, Re_k.transpose().conjugate())

        P1 = blockdiagonalization._calc_stream_reduction_matrix(Re_k, 1)
        P2 = blockdiagonalization._calc_stream_reduction_matrix(Re_k, 2)
        P3 = blockdiagonalization._calc_stream_reduction_matrix(Re_k, 3)

        # Equivalent channels with the stream reduction
        Heq_k_P1 = np.dot(Heq_k, P1)
        Heq_k_P2 = np.dot(Heq_k, P2)
        Heq_k_P3 = np.dot(Heq_k, P3)

        W1 = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k_P1, P1)
        W2 = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k_P2, P2)
        W3 = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k_P3, P3)
        # Note that since P3 is actually including all streams, then the
        # performance is the same as if we don't reduce streams. However W3
        # and W_full are different matrices, since W3 has to compensate the
        # right multiplication of the equivalent channel by P3 and W_full
        # does not. The performance is the same because no energy is lost
        # due to stream reduction and the Frobenius norms of W3 and W_full
        # are equal.
        W_full = blockdiagonalization.EnhancedBD.calc_receive_filter_user_k(
            Heq_k)

        np.testing.assert_array_almost_equal(np.dot(W1, np.dot(Heq_k, P1)),
                                             np.eye(1))
        np.testing.assert_array_almost_equal(np.dot(W2, np.dot(Heq_k, P2)),
                                             np.eye(2))
        np.testing.assert_array_almost_equal(np.dot(W3, np.dot(Heq_k, P3)),
                                             np.eye(3))
        np.testing.assert_array_almost_equal(np.dot(W_full, Heq_k), np.eye(3))

        overbar_P2 = calcProjectionMatrix(P2)
        expected_W2 = np.dot(
            np.linalg.pinv(np.dot(overbar_P2, np.dot(Heq_k, P2))), overbar_P2)
        np.testing.assert_array_almost_equal(expected_W2, W2)
Example #24
0
    def test_calc_decorrelation_matrix(self):
        A = misc.randn_c(3, 3)

        # B is symmetric and positive semi-definite
        B = np.dot(A, A.conjugate().T)

        Wd = misc.calc_decorrelation_matrix(B)

        D = np.dot(np.dot(Wd.conjugate().T, B), Wd)

        # D must be a diagonal matrix
        np.testing.assert_array_almost_equal(D, np.diag(D.diagonal()))
Example #25
0
    def test_calc_decorrelation_matrix(self):
        A = misc.randn_c(3, 3)

        # B is symmetric and positive semi-definite
        B = np.dot(A, A.conjugate().T)

        Wd = misc.calc_decorrelation_matrix(B)

        D = np.dot(np.dot(Wd.conjugate().T, B), Wd)

        # D must be a diagonal matrix
        np.testing.assert_array_almost_equal(D, np.diag(D.diagonal()))
Example #26
0
    def test_calc_whitening_matrix(self):
        A = misc.randn_c(3, 3)

        # B is symmetric and positive semi-definite
        B = np.dot(A, A.conjugate().T)

        Wd = misc.calc_whitening_matrix(B)

        D = np.dot(np.dot(Wd.conjugate().T, B), Wd)

        # D must be an identity matrix
        np.testing.assert_array_almost_equal(D, np.eye(3))
Example #27
0
    def test_calc_whitening_matrix(self):
        A = misc.randn_c(3, 3)

        # B is symmetric and positive semi-definite
        B = np.dot(A, A.conjugate().T)

        Wd = misc.calc_whitening_matrix(B)

        D = np.dot(np.dot(Wd.conjugate().T, B), Wd)

        # D must be an identity matrix
        np.testing.assert_array_almost_equal(D, np.eye(3))
Example #28
0
    def test_decode(self):
        # xxxxxxxxxx test the case with Ntx=2, NRx=2 xxxxxxxxxxxxxxxxxxxxxx
        Nt = 2
        Nr = 2
        data = np.r_[0:15*Nt]
        channel = randn_c(Nr, Nt)
        self.svdmimo_object.set_channel_matrix(channel)

        encoded_data = self.svdmimo_object.encode(data)
        received_data = channel.dot(encoded_data)
        decoded_data = self.svdmimo_object.decode(received_data)
        np.testing.assert_array_almost_equal(data, decoded_data)
    def test_modulate_and_demodulate(self):
        input_data = np.random.random_integers(0, 1, 20)
        modulated_data = self.bpsk_obj.modulate(input_data)

        awgn_noise = randn_c(20,) * 1e-2

        demodulated_data = self.bpsk_obj.demodulate(modulated_data + awgn_noise)
        np.testing.assert_array_equal(input_data, demodulated_data)

        # Test if an exception is raised for invalid arguments
        with self.assertRaises(ValueError):
            self.bpsk_obj.modulate(2)
    def test_modulate_and_demodulate(self):
        input_data = np.random.random_integers(0, 1, 20)
        modulated_data = self.bpsk_obj.modulate(input_data)

        awgn_noise = randn_c(20, ) * 1e-2

        demodulated_data = self.bpsk_obj.demodulate(modulated_data +
                                                    awgn_noise)
        np.testing.assert_array_equal(input_data, demodulated_data)

        # Test if an exception is raised for invalid arguments
        with self.assertRaises(ValueError):
            self.bpsk_obj.modulate(2)
Example #31
0
    def test_decode(self):
        data = np.r_[0:15]
        num_streams = 3

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Test with an identity channel
        channel = np.eye(num_streams)
        self.mrc_object.set_channel_matrix(channel)
        encoded_data = self.mrc_object.encode(data)
        decoded_data1 = self.mrc_object.decode(encoded_data)
        np.testing.assert_array_almost_equal(decoded_data1, data)

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Test with a random channel and a zero-force filter
        self.mrc_object.set_noise_var(None)  # This should use the ZF filter
        channel = randn_c(4, num_streams)  # 4 receive antennas
        self.mrc_object.set_channel_matrix(channel)
        received_data2 = np.dot(channel, encoded_data)
        decoded_data2 = self.mrc_object.decode(received_data2)
        np.testing.assert_array_almost_equal(decoded_data2, data)

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Test with a random channel and a MMSE filter
        self.mrc_object.set_noise_var(0.00000001)
        channel = randn_c(4, num_streams)  # 4 receive antennas
        self.mrc_object.set_channel_matrix(channel)
        received_data3 = np.dot(channel, encoded_data)
        decoded_data3 = self.mrc_object.decode(received_data3)
        np.testing.assert_array_almost_equal(decoded_data3.round(7), data)

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # test with a single stream
        self.mrc_object.set_noise_var(None)  # This should use the ZF filter
        channel = randn_c(4)  # 4 receive antennas
        self.mrc_object.set_channel_matrix(channel)
        encoded_data2 = self.mrc_object.encode(data)
        received_data4 = np.dot(channel[:,np.newaxis], encoded_data2)
        decoded_data4 = self.mrc_object.decode(received_data4)
        np.testing.assert_array_almost_equal(decoded_data4, data)
    def test_modulate_and_demodulate(self) -> None:
        input_data = np.random.randint(0, 2, 20)
        modulated_data = self.bpsk_obj.modulate(input_data)

        awgn_noise = randn_c(20, ) * 1e-2

        demodulated_data = self.bpsk_obj.demodulate(modulated_data +
                                                    awgn_noise)
        np.testing.assert_array_equal(input_data, demodulated_data)

        # Test if an exception is raised for invalid arguments
        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            self.bpsk_obj.modulate(2)
Example #33
0
    def test_block_diagonalize(self):
        Pu = self.Pu
        noise_var = self.noise_var
        num_users = self.num_users
        num_antenas = self.num_antenas

        channel = randn_c(self.iNr, self.iNt)
        (newH, Ms) = blockdiagonalization.block_diagonalize(
            channel, num_users, Pu, noise_var)

        # xxxxx Test if the channel is really block diagonal xxxxxxxxxxxxxx
        # First we build a 'mask' to filter out the elements in the block
        # diagonal.

        A = np.ones([self.iNrk, self.iNtk])
        mask = block_diag(A, A, A)

        # With the mask we can create a masked array of the block
        # diagonalized channel
        masked_newH = np.ma.masked_array(newH, mask)
        # Now we can sum all elements of this masked array (which
        # effectively means all elements outside the block diagonal) and
        # see if it is close to zero.
        self.assertAlmostEqual(0., np.abs(masked_newH).sum())

        # xxxxx Now lets test the power restriction xxxxxxxxxxxxxxxxxxxxxxx
        # Total power restriction
        total_power = num_users * Pu
        self.assertGreaterEqual(total_power,
                                np.linalg.norm(Ms, 'fro') ** 2)

        # Cummulated number of receive antennas
        cum_Nt = np.cumsum(
            np.hstack([0, np.ones(num_users, dtype=int) * num_antenas]))

        # Individual power restriction of each class
        individual_powers = []
        tol = 1e-12  # Tolerance for the GreaterEqual test
        for i in range(num_users):
            # Most likelly only one base station (the one with the worst
            # channel) will employ a precoder a precoder with total power
            # of `Pu`, while the other base stations will use less power.
            individual_powers.append(
                np.linalg.norm(
                    Ms[:, cum_Nt[i]:cum_Nt[i] + num_antenas], 'fro') ** 2)
            self.assertGreaterEqual(Pu + tol,
                                    individual_powers[-1])
Example #34
0
    def test_block_diagonalize(self):
        Pu = self.Pu
        noise_var = self.noise_var
        num_users = self.num_users
        num_antennas = self.num_antennas

        channel = randn_c(self.iNr, self.iNt)
        (newH,
         Ms) = blockdiagonalization.block_diagonalize(channel, num_users, Pu,
                                                      noise_var)

        # xxxxx Test if the channel is really block diagonal xxxxxxxxxxxxxx
        # First we build a 'mask' to filter out the elements in the block
        # diagonal.

        A = np.ones([self.iNrk, self.iNtk])
        mask = block_diag(A, A, A)

        # With the mask we can create a masked array of the block
        # diagonalized channel
        masked_newH = np.ma.masked_array(newH, mask)
        # Now we can sum all elements of this masked array (which
        # effectively means all elements outside the block diagonal) and
        # see if it is close to zero.
        self.assertAlmostEqual(0., np.abs(masked_newH).sum())

        # xxxxx Now lets test the power restriction xxxxxxxxxxxxxxxxxxxxxxx
        # Total power restriction
        total_power = num_users * Pu
        self.assertGreaterEqual(total_power, np.linalg.norm(Ms, 'fro')**2)

        # accumulated number of receive antennas
        cum_Nt = np.cumsum(
            np.hstack([0, np.ones(num_users, dtype=int) * num_antennas]))

        # Individual power restriction of each class
        individual_powers = []
        tol = 1e-12  # Tolerance for the GreaterEqual test
        for i in range(num_users):
            # Most likely only one base station (the one with the worst
            # channel) will employ a precoder a precoder with total power
            # of `Pu`, while the other base stations will use less power.
            individual_powers.append(
                np.linalg.norm(Ms[:, cum_Nt[i]:cum_Nt[i] + num_antennas],
                               'fro')**2)
            self.assertGreaterEqual(Pu + tol, individual_powers[-1])
Example #35
0
    def test_calc_post_processing_SINRs(self):
        Nr = 1
        Nt = 2
        noise_var = 0.01
        channel = randn_c(Nr, Nt)
        self.alamouti_object.set_channel_matrix(channel)

        # W = self.alamouti_object._calc_precoder(channel)
        # G_H = self.alamouti_object._calc_receive_filter(channel, noise_var)

        expected_sinrs = linear2dB(
            (np.linalg.norm(channel, 'fro')**2)/noise_var)

        # Calculate the SINR using method in the Alamouti class. Note that
        # we only need to pass the noise variance, since the mimo object
        # knows the channel.
        sinrs = self.alamouti_object.calc_SINRs(noise_var)
        np.testing.assert_array_almost_equal(sinrs, expected_sinrs, 2)
    def test_modulate_and_demodulate(self):
        awgn_noise = randn_c(20, ) * 1e-2

        input_data = np.random.randint(0, 4, 20)
        modulated_data = self.psk_obj.modulate(input_data)
        demodulated_data = self.psk_obj.demodulate(modulated_data + awgn_noise)

        np.testing.assert_array_equal(input_data, demodulated_data)

        input_data2 = np.random.randint(0, 8, 20)
        modulated_data2 = self.psk_obj2.modulate(input_data2)
        demodulated_data2 = self.psk_obj2.demodulate(modulated_data2 +
                                                     awgn_noise)
        np.testing.assert_array_equal(input_data2, demodulated_data2)

        # Test if an exception is raised for invalid arguments
        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            self.psk_obj.modulate(4)
        with self.assertRaises(ValueError):
            self.psk_obj2.modulate(10)
Example #37
0
    def test_calc_post_processing_SINRs(self):
        Nr = 3
        Nt = 3
        noise_var = 0.01
        channel = randn_c(Nr, Nt)
        self.svdmimo_object.set_channel_matrix(channel)

        W = self.svdmimo_object._calc_precoder(channel)
        G_H = self.svdmimo_object._calc_receive_filter(channel, noise_var)
        expected_sinrs = linear2dB(calc_SINRs(channel, W, G_H, noise_var))

        # Calculate the SINR using the function in the mimo module. Note
        # that we need to pass the channel, the precoder, the receive
        # filter and the noise variance.
        sinrs = calc_post_processing_SINRs(channel, W, G_H, noise_var)
        np.testing.assert_array_almost_equal(sinrs, expected_sinrs, 2)

        # Calculate the SINR using method in the MIMO class. Note that we
        # only need to pass the noise variance, since the mimo object knows
        # the channel and it can calculate the precoder and receive filter.
        sinrs_other = self.svdmimo_object.calc_linear_SINRs(noise_var)
        np.testing.assert_array_almost_equal(sinrs_other, expected_sinrs, 2)
def gen_codebook(codebook_size, dimension):
    """
    Generate a new codebook.

    Parameters
    ----------
    codebook_size : int
        The number of code words in the codebook.
    dimension : int
        The dimension of each precoder.

    Returns
    -------
    codebook : 2D numpy array
        The generated codebook.
    """
    codebook = np.empty([codebook_size, dimension], dtype=complex)
    for i in range(codebook_size):
        H = misc.randn_c(dimension, 1)
        [U, _, _] = np.linalg.svd(H)
        codebook[i] = U[:, 0]

    return codebook
def gen_codebook(codebook_size, dimension):
    """
    Generate a new codebook.

    Parameters
    ----------
    codebook_size : int
        The number of code words in the codebook.
    dimension : int
        The dimension of each precoder.

    Returns
    -------
    codebook : 2D numpy array
        The generated codebook.
    """
    codebook = np.empty([codebook_size, dimension], dtype=complex)
    for i in range(codebook_size):
        H = misc.randn_c(dimension, 1)
        [U, _, _] = np.linalg.svd(H)
        codebook[i] = U[:, 0]

    return codebook
Example #40
0
    # Perform the Block Diagonalization of the channel
    (newH, Ms) = blockdiagonalization.block_diagonalize(
        # We only add the first np.sum(Nt) columns of big_H
        # because the remaining columns come from the external
        # interference sources, which don't participate in the Block
        # Diagonalization Process.
        multiuser_channel.big_H[:, 0:np.sum(Nt)],
        num_cells,
        transmit_power,
        # noise_var
        1e-50)

    # Prepare the transmit data.
    precoded_data = np.dot(Ms, symbols)
    external_int_data = np.sqrt(pe) * misc.randn_c(ext_int_rank, NSymbs)
    all_data = np.vstack([precoded_data, external_int_data])

    # Pass the precoded data through the channel
    received_signal = multiuser_channel.corrupt_concatenated_data(all_data)

    # Filter the received data
    receive_filter = np.linalg.pinv(newH)
    received_symbols = np.dot(receive_filter, received_signal)

    # Demodulate the filtered symbols
    decoded_symbols = modulator.demodulate(received_symbols)

    # Calculates the number of symbol errors
    num_symbol_errors += np.sum(decoded_symbols != input_data)
    num_symbols += input_data.size
                = quant_small_matrix(
                    true_matrix[rx_start:rx_end, tx_start:tx_end], codebook)

    return quantize_channel


if __name__ == '__main__1':
    codebook_size = 5
    dimension = 4
    C = gen_codebook(codebook_size, dimension)

    Nt = 2
    Nr = 2
    K = 3

    H = misc.randn_c(Nr * K, Nt * K)

    Hquant = my_quant_func(H, Nr, Nt, K, C)

if __name__ == '__main__':
    SNR = 15.0
    noise_var = 1 / dB2Linear(SNR)
    M = 2
    NSymbs = 50
    rep_max = 300
    modulator = fundamental.BPSK()
    K = 3
    Nr = np.ones(K, dtype=int) * 2
    Nt = np.ones(K, dtype=int) * 2
    Ns = np.ones(K, dtype=int) * 1
    multi_user_channel = pyphysim.channels.multiuser.MultiUserChannelMatrix()
Example #42
0
    # Perform the Block Diagonalization of the channel
    (newH, Ms) = blockdiagonalization.block_diagonalize(
        # We only add the first np.sum(Nt) columns of big_H
        # because the remaining columns come from the external
        # interference sources, which don't participate in the Block
        # Diagonalization Process.
        multiuser_channel.big_H[:, 0 : np.sum(Nt)],
        num_cells,
        transmit_power,
        # noise_var
        1e-50,
    )

    # Prepare the transmit data.
    precoded_data = np.dot(Ms, symbols)
    external_int_data = np.sqrt(pe) * misc.randn_c(ext_int_rank, NSymbs)
    all_data = np.vstack([precoded_data, external_int_data])

    # Pass the precoded data through the channel
    received_signal = multiuser_channel.corrupt_concatenated_data(all_data)

    # Filter the received data
    receive_filter = np.linalg.pinv(newH)
    received_symbols = np.dot(receive_filter, received_signal)

    # Demodulate the filtered symbols
    decoded_symbols = modulator.demodulate(received_symbols)

    # Calculates the number of symbol errors
    num_symbol_errors += np.sum(decoded_symbols != input_data)
    num_symbols += input_data.size
    def _run_simulation(self, current_parameters):
        """The _run_simulation method is where the actual code to simulate
        the system is.

        The implementation of this method is required by every subclass of
        SimulationRunner.
        """
        # xxxxx Input parameters (set in the constructor) xxxxxxxxxxxxxxxxx
        NSymbs = current_parameters['NSymbs']
        modulator = current_parameters['modulator']
        M = modulator.M
        SNR = current_parameters["SNR"]
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Input Data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        inputData = np.random.randint(0, M, NSymbs)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Modulate input data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        modulatedData = modulator.modulate(inputData)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Pass through the channel xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        noiseVar = 1. / dB2Linear(SNR)
        noise = misc.randn_c(NSymbs) * np.sqrt(noiseVar)
        receivedData = modulatedData + noise
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Demodulate received data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        demodulatedData = modulator.demodulate(receivedData)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Calculates the symbol and bit error rates xxxxxxxxxxxxxxxxx
        symbolErrors = sum(inputData != demodulatedData)
        bitErrors = misc.count_bit_errors(inputData, demodulatedData)
        numSymbols = inputData.size
        numBits = inputData.size * fundamental.level2bits(M)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Return the simulation results xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        symbolErrorsResult = Result.create(
            "symbol_errors", Result.SUMTYPE, symbolErrors)

        numSymbolsResult = Result.create(
            "num_symbols", Result.SUMTYPE, numSymbols)

        bitErrorsResult = Result.create(
            "bit_errors", Result.SUMTYPE, bitErrors)

        numBitsResult = Result.create("num_bits", Result.SUMTYPE, numBits)

        berResult = Result.create("ber", Result.RATIOTYPE, bitErrors, numBits)

        serResult = Result.create(
            "ser", Result.RATIOTYPE, symbolErrors, numSymbols)

        simResults = SimulationResults()
        simResults.add_result(symbolErrorsResult)
        simResults.add_result(numSymbolsResult)
        simResults.add_result(bitErrorsResult)
        simResults.add_result(numBitsResult)
        simResults.add_result(berResult)
        simResults.add_result(serResult)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        return simResults
Example #44
0
    def _run_simulation(self, current_parameters):
        # xxxxx Input parameters (set in the constructor) xxxxxxxxxxxxxxxxx
        NSymbs = current_parameters["NSymbs"]
        M = self.modulator.M
        Nr = current_parameters["Nr"]
        Nt = current_parameters["Nt"]
        SNR = current_parameters["SNR"]
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Create the channel xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        channel = misc.randn_c(Nr, Nt)
        self.mimo_object.set_channel_matrix(channel)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Input Data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        num_layers = self.mimo_object.getNumberOfLayers()
        inputData = np.random.randint(0, M, NSymbs * num_layers)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Modulate input data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        modulatedData = self.modulator.modulate(inputData)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Encode with the MIMO scheme xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        transmit_signal = self.mimo_object.encode(modulatedData)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Pass through the channel xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        noiseVar = 1 / dB2Linear(SNR)
        awgn_noise = (misc.randn_c(Nr, NSymbs) * np.sqrt(noiseVar))
        received_signal = np.dot(channel, transmit_signal) + awgn_noise
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Decode with the MIMO Scheme xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        mimo_decoded_data = self.mimo_object.decode(received_signal)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Demodulate received data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        demodulatedData = self.modulator.demodulate(mimo_decoded_data)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Calculates the symbol and bit error rates xxxxxxxxxxxxxxxxx
        symbolErrors = sum(inputData != demodulatedData)
        bitErrors = misc.count_bit_errors(inputData, demodulatedData)
        numSymbols = inputData.size
        numBits = inputData.size * fundamental.level2bits(M)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Return the simulation results xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        symbolErrorsResult = Result.create(
            "symbol_errors", Result.SUMTYPE, symbolErrors)

        numSymbolsResult = Result.create(
            "num_symbols", Result.SUMTYPE, numSymbols)

        bitErrorsResult = Result.create("bit_errors",
                                        Result.SUMTYPE, bitErrors)

        numBitsResult = Result.create("num_bits", Result.SUMTYPE, numBits)

        berResult = Result.create("ber", Result.RATIOTYPE, bitErrors, numBits)

        serResult = Result.create(
            "ser", Result.RATIOTYPE, symbolErrors, numSymbols)

        simResults = SimulationResults()
        simResults.add_result(symbolErrorsResult)
        simResults.add_result(numSymbolsResult)
        simResults.add_result(bitErrorsResult)
        simResults.add_result(numBitsResult)
        simResults.add_result(berResult)
        simResults.add_result(serResult)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        return simResults
Example #45
0
    def _run_simulation(self, current_parameters):
        """The _run_simulation method is where the actual code to simulate
        the system is.

        The implementation of this method is required by every subclass of
        SimulationRunner.
        """
        # xxxxx Input parameters (set in the constructor) xxxxxxxxxxxxxxxxx
        NSymbs = current_parameters['NSymbs']
        modulator = current_parameters['modulator']
        M = modulator.M
        SNR = current_parameters["SNR"]
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Input Data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        inputData = np.random.randint(0, M, NSymbs)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Modulate input data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        modulatedData = modulator.modulate(inputData)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Pass through the channel xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        noiseVar = 1. / dB2Linear(SNR)
        noise = misc.randn_c(NSymbs) * np.sqrt(noiseVar)
        receivedData = modulatedData + noise
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Demodulate received data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        demodulatedData = modulator.demodulate(receivedData)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Calculates the symbol and bit error rates xxxxxxxxxxxxxxxxx
        symbolErrors = sum(inputData != demodulatedData)
        bitErrors = misc.count_bit_errors(inputData, demodulatedData)
        numSymbols = inputData.size
        numBits = inputData.size * fundamental.level2bits(M)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Return the simulation results xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        symbolErrorsResult = Result.create("symbol_errors", Result.SUMTYPE,
                                           symbolErrors)

        numSymbolsResult = Result.create("num_symbols", Result.SUMTYPE,
                                         numSymbols)

        bitErrorsResult = Result.create("bit_errors", Result.SUMTYPE, bitErrors)

        numBitsResult = Result.create("num_bits", Result.SUMTYPE, numBits)

        berResult = Result.create("ber", Result.RATIOTYPE, bitErrors, numBits)

        serResult = Result.create("ser", Result.RATIOTYPE, symbolErrors,
                                  numSymbols)

        simResults = SimulationResults()
        simResults.add_result(symbolErrorsResult)
        simResults.add_result(numSymbolsResult)
        simResults.add_result(bitErrorsResult)
        simResults.add_result(numBitsResult)
        simResults.add_result(berResult)
        simResults.add_result(serResult)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        return simResults
                = quant_small_matrix(
                    true_matrix[rx_start:rx_end, tx_start:tx_end], codebook)

    return quantize_channel


if __name__ == '__main__1':
    codebook_size = 5
    dimension = 4
    C = gen_codebook(codebook_size, dimension)

    Nt = 2
    Nr = 2
    K = 3

    H = misc.randn_c(Nr * K, Nt * K)

    Hquant = my_quant_func(H, Nr, Nt, K, C)


if __name__ == '__main__':
    SNR = 15.0
    noise_var = 1 / dB2Linear(SNR)
    M = 2
    NSymbs = 50
    rep_max = 300
    modulator = fundamental.BPSK()
    K = 3
    Nr = np.ones(K, dtype=int) * 2
    Nt = np.ones(K, dtype=int) * 2
    Ns = np.ones(K, dtype=int) * 1