forked from qh4869/RSMA_mod
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptiPrecode_noma.m
71 lines (61 loc) · 2.32 KB
/
optiPrecode_noma.m
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
function [precoder, wsr] = optiPrecode_noma(config, equalizer, mmseWeight, ...
H, permVec, snr)
% Fn: the second iteration step
%
% In:
% - equalizer: [g]
% - mmseWeight: [u]
% - H: user channel (before Hermitian)
% - permVec: SIC user order
% - snr: transmit power to noise
%
% Out:
% - ordPrecoder: optimal result by cvx
% - wsr: optimal target value
% initialization
ordH = H(:, permVec); % the first column is the first SIC user
ordWeight = config.weight(:, permVec);
cvx_begin quiet
variable ordPrecoder(config.tx, config.Nuser) complex;
% initial variables
% total power (ordered user * ordered layer) [T]
% note that it's the function of ordPrecoders
tolPow = cvx(zeros(config.Nuser));
mse = cvx(zeros(config.Nuser)); % [\epsilon]
wmse = cvx(zeros(config.Nuser)); % [\xi] augment weighted MSE
rate = cvx(zeros(config.Nuser)); % data rate of each SIC process
for iOrdUser = 1 : config.Nuser
for iOrdLayer = 1 : iOrdUser
tolPow(iOrdUser, iOrdLayer) = sum_square_abs(ordH(:, iOrdUser)' ...
* ordPrecoder(:, iOrdLayer:end), 2) + 1;
mse(iOrdUser, iOrdLayer) = square_abs(equalizer(iOrdUser, iOrdLayer)) ...
* tolPow(iOrdUser, iOrdLayer) ...
- 2 * real(equalizer(iOrdUser, iOrdLayer) * ordH(:, iOrdUser)' ...
* ordPrecoder(:, iOrdLayer)) + 1;
wmse(iOrdUser, iOrdLayer) = mmseWeight(iOrdUser, iOrdLayer) ...
* mse(iOrdUser, iOrdLayer) - log2(mmseWeight(iOrdUser, iOrdLayer));
rate(iOrdUser, iOrdLayer) = 1 - wmse(iOrdUser, iOrdLayer);
end
for iOrdLayer = iOrdUser + 1 : config.Nuser
tolPow(iOrdUser, iOrdLayer) = NaN;
mse(iOrdUser, iOrdLayer) = NaN;
wmse(iOrdUser, iOrdLayer) = NaN;
rate(iOrdUser, iOrdLayer) = NaN;
end
end
wsr = 0;
for iOrdLayer = 1 : config.Nuser
layerRate = rate(:, iOrdLayer);
clsIdx = cvx_classify(layerRate);
wsr = wsr + ordWeight(iOrdLayer) ...
* min(layerRate(clsIdx ~= 13)); % ref: cvx_classify.m
end
maximize wsr;
subject to
ordPrecoder(:)' * ordPrecoder(:) <= snr;
cvx_end
precoder = zeros(size(ordPrecoder));
for i = 1 : permVec
precoder(:, permVec(i)) = ordPrecoder(:, i);
end
end