-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommsetup.py
151 lines (109 loc) · 3.48 KB
/
commsetup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import numpy as np
########################################
# Private functions
########################################
def nonstationary(M, K, D):
""" Output the diagonal matrix regarding non-stationary effects.
Parameters
----------
M : int
Number of antennas.
K : int
Number of users.
D : int
Number of visible antennas per user.
Returns
-------
diag : 3D ndarray of numpy.cdouble
Collection of diagonal matrices.
shape: (K,M,M)
"""
# Non-stationary
diag = np.zeros((M, K), dtype=np.cdouble)
if D != M:
# Generating VRs
offset = D//2
centers = np.random.randint(M, size=K, dtype=np.int)
if D%2 == 0:
upper = centers + offset
else:
upper = centers + (offset + 1)
lower = centers - offset
# Check correctness of the sets
upper[upper >= M] = M-1
lower[lower < 0] = 0
# Generating diagonal matrices
zerosM = np.zeros(M, dtype=np.cdouble)
for k in range(K):
els = zerosM.copy()
els[lower[k]:upper[k]] = 1
diag[:, k] = els
# Normalization
diag *= M/D
else:
diag = np.ones((M, K))
return diag
########################################
# Public Functions
########################################
def massive_mimo(M, K, nchnlreal):
""" Generate a channel matrix considering equal power control, that is,
we disregard pathloss and other wireless channel effects.
Parameters
----------
M : int
Number of base station antennas.
K : int
Number of users.
nchnlreal : int
Number of channel realizations.
Returns
-------
H : 3D ndarray of numpy.cdouble
Collection of nchnlreal channel matrices.
shape: (nchnlreal,M,K)
"""
# Generate uncorrelated channels
H = np.sqrt(1/2)*(np.random.randn(nchnlreal, M, K) + 1j*np.random.randn(nchnlreal, M, K))
return H
def extra_large_mimo(M, K, D, nchnlreal):
""" Generate a channel matrix considering equal power control (no pathloss)
and non-stationarities channels.
Parameters
----------
M : int
Number of base station antennas.
K : int
Number of users.
D : int
Number of effective users served by each antenna.
nchnlreal : int
Number of channel realizations.
Returns
-------
H : 3D ndarray of numpy.cdouble
Collection of nchnlreal channel matrices.
shape: (nchnlreal,M,K)
"""
# Prepare to save the diagonals of the Dm matrix for each antenna m
diags = np.zeros((M, K), dtype=np.cdouble)
# Go through all the antenna elements
for m in range(M):
# Define a control variable
control = False
while not(control):
# Generate a random sequence of ones
sequence = np.random.randint(0, 2, size=K)
# Check the sum of the sequences
if sequence.sum() == D:
# Store the sequence obtained
diags[m] = sequence.copy()
# Update the control variable
control = True
# Generate uncorrelated channels
Huncorr = np.sqrt((1/2))*(np.random.randn(nchnlreal, M, K) + 1j*np.random.randn(nchnlreal, M, K))
# Go through all the antenna elements
for m in range(M):
# Apply the diagonal matrix structure
Huncorr[:, m, :] = diags[m] * Huncorr[:, m, :]
return Huncorr