├── Figure1 ├── channel_generate.m ├── data_processing │ ├── data_processing.m │ ├── one_and_one_data │ │ ├── gpi_method.mat │ │ ├── low_complexity.mat │ │ ├── multicast_sca.mat │ │ ├── multicast_wmmse.mat │ │ ├── noma_sca.mat │ │ ├── noma_wmmse.mat │ │ ├── rsma_sca.mat │ │ ├── rsma_wmmse.mat │ │ ├── sdma_sca.mat │ │ └── sdma_wmmse.mat │ └── zero_point_three_data │ │ ├── gpi_method.mat │ │ ├── low_complexity.mat │ │ ├── multicast_sca.mat │ │ ├── multicast_wmmse.mat │ │ ├── noma_sca.mat │ │ ├── noma_wmmse.mat │ │ ├── rsma_sca.mat │ │ ├── rsma_wmmse.mat │ │ ├── sdma_sca.mat │ │ └── sdma_wmmse.mat ├── one_and_one │ ├── GPI │ │ ├── channel.mat │ │ ├── gpi_method.m │ │ ├── gpi_method.mat │ │ └── gpi_method_main.m │ ├── low_complexity │ │ ├── channel.mat │ │ ├── lowComplexity.m │ │ ├── low_complexity.mat │ │ ├── low_complexity_main.m │ │ └── maxMinRate.m │ ├── sca │ │ ├── multicast │ │ │ ├── channel.mat │ │ │ ├── multicast_sca.m │ │ │ ├── multicast_sca.mat │ │ │ ├── multicast_sca_main.m │ │ │ └── multicast_sca_update.m │ │ ├── noma │ │ │ ├── channel.mat │ │ │ ├── noma_sca.m │ │ │ ├── noma_sca.mat │ │ │ ├── noma_sca_main.m │ │ │ └── noma_sca_update.m │ │ ├── rsma │ │ │ ├── channel.mat │ │ │ ├── rsma_sca.m │ │ │ ├── rsma_sca.mat │ │ │ ├── rsma_sca_main.m │ │ │ └── rsma_sca_update.m │ │ └── sdma │ │ │ ├── channel.mat │ │ │ ├── sdma_sca.m │ │ │ ├── sdma_sca.mat │ │ │ ├── sdma_sca_main.m │ │ │ └── sdma_sca_update.m │ └── wmmse │ │ ├── multicast │ │ ├── channel.mat │ │ ├── multicast_wmmse.m │ │ ├── multicast_wmmse.mat │ │ ├── multicast_wmmse_main.m │ │ └── multicast_wmmse_update.m │ │ ├── noma │ │ ├── channel.mat │ │ ├── noma_wmmse.m │ │ ├── noma_wmmse.mat │ │ ├── noma_wmmse_main.m │ │ └── noma_wmmse_update.m │ │ ├── rsma │ │ ├── channel.mat │ │ ├── rsma_wmmse.m │ │ ├── rsma_wmmse.mat │ │ ├── rsma_wmmse_main.m │ │ └── rsma_wmmse_update.m │ │ └── sdma │ │ ├── channel.mat │ │ ├── sdma_wmmse.m │ │ ├── sdma_wmmse.mat │ │ ├── sdma_wmmse_main.m │ │ └── sdma_wmmse_update.m └── one_and_zero_point_three │ ├── GPI_method │ ├── channel.mat │ ├── gpi_method.m │ ├── gpi_method.mat │ └── gpi_method_main.m │ ├── low_complexity │ ├── channel.mat │ ├── lowComplexity.m │ ├── low_complexity.mat │ ├── low_complexity_main.m │ └── maxMinRate.m │ ├── sca │ ├── multicast │ │ ├── channel.mat │ │ ├── multicast_sca.m │ │ ├── multicast_sca.mat │ │ ├── multicast_sca_main.m │ │ └── multicast_sca_update.m │ ├── noma │ │ ├── channel.mat │ │ ├── noma_sca.m │ │ ├── noma_sca.mat │ │ ├── noma_sca_main.m │ │ └── noma_sca_update.m │ ├── rsma │ │ ├── channel.mat │ │ ├── rsma_sca.m │ │ ├── rsma_sca.mat │ │ ├── rsma_sca_main.m │ │ └── rsma_sca_update.m │ └── sdma │ │ ├── channel.mat │ │ ├── sdma_sca.m │ │ ├── sdma_sca.mat │ │ ├── sdma_sca_main.m │ │ └── sdma_sca_update.m │ └── wmmse │ ├── multicast │ ├── channel.mat │ ├── multicast_wmmse.m │ ├── multicast_wmmse.mat │ ├── multicast_wmmse_main.m │ └── multicast_wmmse_update.m │ ├── noma │ ├── channel.mat │ ├── noma_wmmse.m │ ├── noma_wmmse.mat │ ├── noma_wmmse_main.m │ └── noma_wmmse_update.m │ ├── rsma │ ├── channel.mat │ ├── rsma_wmmse.m │ ├── rsma_wmmse.mat │ ├── rsma_wmmse_main.m │ └── rsma_wmmse_update.m │ └── sdma │ ├── channel.mat │ ├── sdma_wmmse.m │ ├── sdma_wmmse.mat │ ├── sdma_wmmse_main.m │ └── sdma_wmmse_update.m ├── Figure2 ├── lowComplexity.m ├── maxMinRate.m └── optimalT.m ├── Figure3 ├── lowComplexity.m ├── maxMinRate.m └── relativeGain.m └── README.md /Figure1/channel_generate.m: -------------------------------------------------------------------------------- 1 | % This script generates 100 channel random realizations. 2 | clear all; 3 | clc; 4 | K = 2; 5 | Nt = 2; 6 | channel_num = 100; 7 | Sigma = [1, 1]; 8 | 9 | channel = generate_channel(Nt, K, channel_num, Sigma); 10 | filename = 'channel.mat'; 11 | 12 | save(filename); 13 | 14 | function channel = generate_channel(Nt, K, channel_num, Sigma) 15 | channel = sqrt(Sigma/2) .* (randn(Nt, K, channel_num) + 1j*randn(Nt, K, channel_num)); 16 | end 17 | -------------------------------------------------------------------------------- /Figure1/data_processing/data_processing.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load('./zero_point_three_data/gpi_method.mat', 'Sigma', 'gpi_method_mmf_rate_list', 'gpi_method_time_list', 'snrdB_list'); 5 | load('./zero_point_three_data/low_complexity.mat', 'low_complexity_mmf_rate_list', 'low_complexity_time_list'); 6 | load('./zero_point_three_data/multicast_sca.mat', 'multicast_sca_mmf_rate_list', 'multicast_sca_time_list'); 7 | load('./zero_point_three_data/multicast_wmmse.mat', 'multicast_wmmse_mmf_rate_list', 'multicast_wmmse_time_list'); 8 | load('./zero_point_three_data/noma_sca.mat', 'noma_sca_mmf_rate_list', 'noma_sca_time_list'); 9 | load('./zero_point_three_data/noma_wmmse.mat', 'noma_wmmse_mmf_rate_list', 'noma_wmmse_time_list'); 10 | load('./zero_point_three_data/rsma_sca.mat', 'rsma_sca_mmf_rate_list', 'rsma_sca_time_list'); 11 | load('./zero_point_three_data/rsma_wmmse.mat', 'rsma_wmmse_mmf_rate_list', 'rsma_wmmse_time_list'); 12 | load('./zero_point_three_data/sdma_sca.mat', 'sdma_sca_mmf_rate_list', 'sdma_sca_time_list'); 13 | load('./zero_point_three_data/sdma_wmmse.mat', 'sdma_wmmse_mmf_rate_list', 'sdma_wmmse_time_list'); 14 | 15 | figure; 16 | set(gcf, 'Position', [100 100 2400, 800]); 17 | subplot('Position', [0.03, 0.22, 0.28, 0.7]); 18 | hold on; 19 | plot(snrdB_list, rsma_sca_mmf_rate_list, ... 20 | 'Color', 'green', ... 21 | 'LineStyle', '-', ... 22 | 'Marker', "none", ... 23 | 'DisplayName', 'RSMA-SCA', ... 24 | 'LineWidth', 2, ... 25 | 'MarkerSize', 7); 26 | plot(snrdB_list, rsma_wmmse_mmf_rate_list, ... 27 | 'Color', 'green', ... 28 | 'LineStyle', ':', ... 29 | 'Marker', '^', ... 30 | 'DisplayName', 'RSMA-WMMSE', ... 31 | 'LineWidth', 4, ... 32 | 'MarkerSize', 9); 33 | plot(snrdB_list, noma_sca_mmf_rate_list, ... 34 | 'Color', '#FF8C00', ... 35 | 'LineStyle', '-', ... 36 | 'Marker', "none", ... 37 | 'DisplayName', 'NOMA-SCA', ... 38 | 'LineWidth', 2, ... 39 | 'MarkerSize', 7); 40 | plot(snrdB_list, noma_wmmse_mmf_rate_list, ... 41 | 'Color', '#FF8C00', ... 42 | 'LineStyle', ':', ... 43 | 'Marker', '+', ... 44 | 'DisplayName', 'NOMA-WMMSE', ... 45 | 'LineWidth', 4, ... 46 | 'MarkerSize', 9); 47 | plot(snrdB_list, sdma_sca_mmf_rate_list, ... 48 | 'Color', '#05B9E2', ... 49 | 'LineStyle', '-', ... 50 | 'Marker', "none", ... 51 | 'DisplayName', 'SDMA-SCA', ... 52 | 'LineWidth', 2, ... 53 | 'MarkerSize', 7); 54 | plot(snrdB_list, sdma_wmmse_mmf_rate_list, ... 55 | 'Color', '#05B9E2', ... 56 | 'LineStyle', ':', ... 57 | 'Marker', 'x', ... 58 | 'DisplayName', 'SDMA-WMMSE', ... 59 | 'LineWidth', 4, ... 60 | 'MarkerSize', 9); 61 | plot(snrdB_list, multicast_sca_mmf_rate_list, ... 62 | 'Color', '#8983BF', ... 63 | 'LineStyle', '-', ... 64 | 'Marker', "none", ... 65 | 'DisplayName', 'Multicast-SCA', ... 66 | 'LineWidth', 2, ... 67 | 'MarkerSize', 7); 68 | plot(snrdB_list, multicast_wmmse_mmf_rate_list, ... 69 | 'Color', '#8983BF', ... 70 | 'LineStyle', ':', ... 71 | 'Marker', 'square', ... 72 | 'DisplayName', 'Multicast-WMMSE', ... 73 | 'LineWidth', 4, ... 74 | 'MarkerSize', 9); 75 | plot(snrdB_list, gpi_method_mmf_rate_list, ... 76 | 'Color', 'black', ... 77 | 'LineStyle', '-', ... 78 | 'Marker', "none", ... 79 | 'DisplayName', 'RSMA-GPI', ... 80 | 'LineWidth', 2, ... 81 | 'MarkerSize', 7); 82 | plot(snrdB_list, low_complexity_mmf_rate_list, ... 83 | 'Color', 'red', ... 84 | 'LineStyle', '-', ... 85 | 'Marker', "none", ... 86 | 'DisplayName', 'Proposed Low Complexity Algorithm', ... 87 | 'LineWidth', 2, ... 88 | 'MarkerSize', 7); 89 | xlabel('SNR [dB]', 'FontSize', 22); 90 | ylabel('MMF Rate [bit/s/Hz]', 'FontSize', 22); 91 | legend('FontSize', 22); 92 | set(legend, 'Position', [0.45, 0.005, 0.1, 0.1], 'NumColumns', 6); 93 | grid on; 94 | box on; 95 | set(gca, 'FontSize', 22); 96 | title(strcat('(a){ }', '\sigma_1 = ', sprintf('%.1f,', Sigma(1)), '{ }', '\sigma_2 = ', sprintf('%.1f', Sigma(2))), 'FontName', 'Times New Roman', 'FontSize', 22); 97 | 98 | subplot('Position', [0.71, 0.22, 0.28, 0.7]); 99 | hold on; 100 | plot(snrdB_list, log10(rsma_sca_time_list), ... 101 | 'Color', 'green', ... 102 | 'LineStyle', '-', ... 103 | 'Marker', "none", ... 104 | 'DisplayName', 'RSMA-SCA', ... 105 | 'LineWidth', 2, ... 106 | 'MarkerSize', 7); 107 | plot(snrdB_list, log10(rsma_wmmse_time_list), ... 108 | 'Color', 'green', ... 109 | 'LineStyle', ':', ... 110 | 'Marker', '^', ... 111 | 'DisplayName', 'RSMA-WMMSE', ... 112 | 'LineWidth', 4, ... 113 | 'MarkerSize', 9); 114 | plot(snrdB_list, log10(noma_sca_time_list), ... 115 | 'Color', '#FF8C00', ... 116 | 'LineStyle', '-', ... 117 | 'Marker', "none", ... 118 | 'DisplayName', 'NOMA-SCA', ... 119 | 'LineWidth', 2, ... 120 | 'MarkerSize', 7); 121 | plot(snrdB_list, log10(noma_wmmse_time_list), ... 122 | 'Color', '#FF8C00', ... 123 | 'LineStyle', ':', ... 124 | 'Marker', '+', ... 125 | 'DisplayName', 'NOMA-WMMSE', ... 126 | 'LineWidth', 4, ... 127 | 'MarkerSize', 9); 128 | plot(snrdB_list, log10(sdma_sca_time_list), ... 129 | 'Color', '#05B9E2', ... 130 | 'LineStyle', '-', ... 131 | 'Marker', "none", ... 132 | 'DisplayName', 'SDMA-SCA', ... 133 | 'LineWidth', 2, ... 134 | 'MarkerSize', 7); 135 | plot(snrdB_list, log10(sdma_wmmse_time_list), ... 136 | 'Color', '#05B9E2', ... 137 | 'LineStyle', ':', ... 138 | 'Marker', 'x', ... 139 | 'DisplayName', 'SDMA-WMMSE', ... 140 | 'LineWidth', 4, ... 141 | 'MarkerSize', 9); 142 | plot(snrdB_list, log10(multicast_sca_time_list), ... 143 | 'Color', '#8983BF', ... 144 | 'LineStyle', '-', ... 145 | 'Marker', "none", ... 146 | 'DisplayName', 'Multicast-SCA', ... 147 | 'LineWidth', 2, ... 148 | 'MarkerSize', 7); 149 | plot(snrdB_list, log10(multicast_wmmse_time_list), ... 150 | 'Color', '#8983BF', ... 151 | 'LineStyle', ':', ... 152 | 'Marker', 'square', ... 153 | 'DisplayName', 'Multicast-WMMSE', ... 154 | 'LineWidth', 4, ... 155 | 'MarkerSize', 9); 156 | plot(snrdB_list, log10(gpi_method_time_list), ... 157 | 'Color', 'black', ... 158 | 'LineStyle', '-', ... 159 | 'Marker', "none", ... 160 | 'DisplayName', 'GPI-MMF-RS', ... 161 | 'LineWidth', 2, ... 162 | 'MarkerSize', 7); 163 | plot(snrdB_list, log10(low_complexity_time_list), ... 164 | 'Color', 'red', ... 165 | 'LineStyle', '-', ... 166 | 'Marker', "none", ... 167 | 'DisplayName', 'Proposed Low Complexity Algorithm', ... 168 | 'LineWidth', 2, ... 169 | 'MarkerSize', 7); 170 | xlabel('SNR [dB]', 'FontSize', 22); 171 | ylabel('CPU Time [s]', 'FontSize', 22); 172 | %legend('FontSize', 13); 173 | %set(legend, 'Location', 'SouthOutside', 'NumColumns', 6); 174 | grid on; 175 | box on; 176 | ax = gca(); 177 | YTickLabel = {}; 178 | for item = ax.YTick 179 | str = sprintf('10^{%d}', item); 180 | YTickLabel = [YTickLabel, str]; 181 | end 182 | ax.YTickLabel = YTickLabel; 183 | ax.XTick = snrdB_list; 184 | set(gca, 'FontSize', 22); 185 | title(strcat('(c){ }', '\sigma_1 = ', sprintf('%.1f, ', Sigma(1)), '{ }', '\sigma_2 = ', sprintf('%.1f', Sigma(2))), 'FontName', 'Times New Roman', 'FontSize', 22); 186 | 187 | clear *list Sigma; 188 | 189 | load('./one_and_one_data/gpi_method.mat', 'K', 'Nt', 'Sigma', 'channel_num', 'gpi_method_mmf_rate_list', 'gpi_method_time_list', 'snrdB_list'); 190 | load('./one_and_one_data/low_complexity.mat', 'low_complexity_mmf_rate_list', 'low_complexity_time_list'); 191 | load('./one_and_one_data/multicast_sca.mat', 'multicast_sca_mmf_rate_list', 'multicast_sca_time_list'); 192 | load('./one_and_one_data/multicast_wmmse.mat', 'multicast_wmmse_mmf_rate_list', 'multicast_wmmse_time_list'); 193 | load('./one_and_one_data/noma_sca.mat', 'noma_sca_mmf_rate_list', 'noma_sca_time_list'); 194 | load('./one_and_one_data/noma_wmmse.mat', 'noma_wmmse_mmf_rate_list', 'noma_wmmse_time_list'); 195 | load('./one_and_one_data/rsma_sca.mat', 'rsma_sca_mmf_rate_list', 'rsma_sca_time_list'); 196 | load('./one_and_one_data/rsma_wmmse.mat', 'rsma_wmmse_mmf_rate_list', 'rsma_wmmse_time_list'); 197 | load('./one_and_one_data/sdma_sca.mat', 'sdma_sca_mmf_rate_list', 'sdma_sca_time_list'); 198 | load('./one_and_one_data/sdma_wmmse.mat', 'sdma_wmmse_mmf_rate_list', 'sdma_wmmse_time_list'); 199 | 200 | subplot('Position', [0.36, 0.22, 0.28, 0.7]); 201 | hold on; 202 | plot(snrdB_list, rsma_sca_mmf_rate_list, ... 203 | 'Color', 'green', ... 204 | 'LineStyle', '-', ... 205 | 'Marker', "none", ... 206 | 'DisplayName', 'RSMA-SCA', ... 207 | 'LineWidth', 2, ... 208 | 'MarkerSize', 7); 209 | plot(snrdB_list, rsma_wmmse_mmf_rate_list, ... 210 | 'Color', 'green', ... 211 | 'LineStyle', ':', ... 212 | 'Marker', '^', ... 213 | 'DisplayName', 'RSMA-WMMSE', ... 214 | 'LineWidth', 4, ... 215 | 'MarkerSize', 9); 216 | plot(snrdB_list, noma_sca_mmf_rate_list, ... 217 | 'Color', '#FF8C00', ... 218 | 'LineStyle', '-', ... 219 | 'Marker', "none", ... 220 | 'DisplayName', 'NOMA-SCA', ... 221 | 'LineWidth', 2, ... 222 | 'MarkerSize', 7); 223 | plot(snrdB_list, noma_wmmse_mmf_rate_list, ... 224 | 'Color', '#FF8C00', ... 225 | 'LineStyle', ':', ... 226 | 'Marker', '+', ... 227 | 'DisplayName', 'NOMA-WMMSE', ... 228 | 'LineWidth', 4, ... 229 | 'MarkerSize', 9); 230 | plot(snrdB_list, sdma_sca_mmf_rate_list, ... 231 | 'Color', '#05B9E2', ... 232 | 'LineStyle', '-', ... 233 | 'Marker', "none", ... 234 | 'DisplayName', 'SDMA-SCA', ... 235 | 'LineWidth', 2, ... 236 | 'MarkerSize', 7); 237 | plot(snrdB_list, sdma_wmmse_mmf_rate_list, ... 238 | 'Color', '#05B9E2', ... 239 | 'LineStyle', ':', ... 240 | 'Marker', 'x', ... 241 | 'DisplayName', 'SDMA-WMMSE', ... 242 | 'LineWidth', 4, ... 243 | 'MarkerSize', 9); 244 | plot(snrdB_list, multicast_sca_mmf_rate_list, ... 245 | 'Color', '#8983BF', ... 246 | 'LineStyle', '-', ... 247 | 'Marker', "none", ... 248 | 'DisplayName', 'Multicast-SCA', ... 249 | 'LineWidth', 2, ... 250 | 'MarkerSize', 7); 251 | plot(snrdB_list, multicast_wmmse_mmf_rate_list, ... 252 | 'Color', '#8983BF', ... 253 | 'LineStyle', ':', ... 254 | 'Marker', 'square', ... 255 | 'DisplayName', 'Multicast-WMMSE', ... 256 | 'LineWidth', 4, ... 257 | 'MarkerSize', 9); 258 | plot(snrdB_list, gpi_method_mmf_rate_list, ... 259 | 'Color', 'black', ... 260 | 'LineStyle', '-', ... 261 | 'Marker', "none", ... 262 | 'DisplayName', 'RSMA-GPI', ... 263 | 'LineWidth', 2, ... 264 | 'MarkerSize', 7); 265 | plot(snrdB_list, low_complexity_mmf_rate_list, ... 266 | 'Color', 'red', ... 267 | 'LineStyle', '-', ... 268 | 'Marker', "none", ... 269 | 'DisplayName', 'Proposed Low Complexity Algorithm', ... 270 | 'LineWidth', 2, ... 271 | 'MarkerSize', 7); 272 | xlabel('SNR [dB]', 'FontSize', 22); 273 | ylabel('MMF Rate [bit/s/Hz]', 'FontSize', 22); 274 | grid on; 275 | box on; 276 | set(gca, 'FontSize', 22); 277 | title(strcat('(b){ }', '\sigma_1 = ', sprintf('%.1f, ', Sigma(1)), '{ }', '\sigma_2 = ', sprintf('%.1f', Sigma(2))), 'FontName', 'Times New Roman', 'FontSize', 22); 278 | -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/gpi_method.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/gpi_method.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/low_complexity.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/low_complexity.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/multicast_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/multicast_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/multicast_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/multicast_wmmse.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/noma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/noma_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/noma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/noma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/rsma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/rsma_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/rsma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/rsma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/sdma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/sdma_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/one_and_one_data/sdma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/one_and_one_data/sdma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/gpi_method.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/gpi_method.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/low_complexity.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/low_complexity.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/multicast_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/multicast_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/multicast_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/multicast_wmmse.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/noma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/noma_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/noma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/noma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/rsma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/rsma_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/rsma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/rsma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/sdma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/sdma_sca.mat -------------------------------------------------------------------------------- /Figure1/data_processing/zero_point_three_data/sdma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/data_processing/zero_point_three_data/sdma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/GPI/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/GPI/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/GPI/gpi_method.m: -------------------------------------------------------------------------------- 1 | function [P, p_c, c, mmf_rate] = gpi_method(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | noise = ones(K, 1); 6 | 7 | P_c = Pt * 0.5; 8 | P_p = (Pt-P_c) / K; 9 | 10 | [U, ~, ~] = svd(H); 11 | p_c = U(:,1) * sqrt(P_c); 12 | P = H ./ vecnorm(H) * sqrt(P_p); 13 | 14 | gamma_min = 0; 15 | gamma_max = 100; 16 | gamma_num = 1001; 17 | 18 | alpha = 0.1; 19 | 20 | T_k = sum(square_abs(H'*P), 2) + noise; 21 | T_ck = T_k + square_abs(H'*p_c); 22 | 23 | rate_c = log2(T_ck ./ T_k); 24 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 25 | 26 | rate_p_sorted = sort(rate_p, 'ascend'); 27 | x = min(rate_c); 28 | y = min((x+cumsum(rate_p_sorted)) ./ (1:K)'); 29 | 30 | max_mmf_rate = y; 31 | corresponding_f = [p_c; reshape(P, K*Nt, 1)]; 32 | 33 | f = corresponding_f; 34 | c = max(y - rate_p, 0); 35 | f_last = f; 36 | 37 | for gamma = linspace(gamma_min, gamma_max, gamma_num) 38 | 39 | for n = 1:1000 40 | 41 | A = zeros(Nt*(K+1), Nt*(K+1), K); 42 | B = zeros(Nt*(K+1)); 43 | C = zeros(Nt*(K+1)); 44 | D = zeros(Nt*(K+1)); 45 | 46 | for k = 1:K 47 | A_k = zeros(Nt); 48 | for m = 1:K 49 | A_k = blkdiag(A_k, H(:, k)*H(:, k)'); 50 | end 51 | A(:, :, k) = A_k + eye(Nt*(K+1))/Pt; 52 | B(:, :, k) = A(:, :, k) - blkdiag(zeros(Nt*k), H(:, k)*H(:, k)', zeros(Nt*(K-k))); 53 | C(:, :, k) = A(:, :, k) + blkdiag(H(:, k)*H(:, k)', zeros(Nt*K)); 54 | D(:, :, k) = A(:, :, k); 55 | end 56 | 57 | T_k = sum(square_abs(H'*P), 2) + noise; 58 | T_ck = T_k + square_abs(H'*p_c); 59 | 60 | rate_c = log2(T_ck ./ T_k); 61 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 62 | 63 | ratio_c = exp(-1/alpha*(rate_c)) / sum(exp(-1/alpha*(rate_c))); 64 | ratio_t = exp(-1/alpha*(c+rate_p)) / sum(exp(-1/alpha*(c+rate_p))); 65 | 66 | E = zeros(Nt*(K+1)); 67 | F = zeros(Nt*(K+1)); 68 | for k = 1:K 69 | E = E + ratio_t(k)*A(:, :, k)/(f'*A(:, :, k)*f) + ratio_c(k)*gamma*C(:, :, k)/(f'*C(:, :, k)*f); 70 | F = F + ratio_t(k)*B(:, :, k)/(f'*B(:, :, k)*f) + ratio_c(k)*gamma*D(:, :, k)/(f'*D(:, :, k)*f); 71 | end 72 | 73 | f = F \ (E*f); 74 | f = f / norm(f) * sqrt(Pt); 75 | 76 | e = norm(f - f_last, 'inf'); 77 | if e < tolerance 78 | break; 79 | end 80 | 81 | f_last = f; 82 | end 83 | 84 | p_c = f(1:Nt); 85 | P = reshape(f(Nt+1:end), Nt, K); 86 | 87 | T_k = sum(square_abs(H'*P), 2) + noise; 88 | T_ck = T_k + square_abs(H'*p_c); 89 | 90 | rate_c = log2(T_ck ./ T_k); 91 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 92 | 93 | rate_p_sorted = sort(rate_p, 'ascend'); 94 | x = min(rate_c); 95 | y = min((x+cumsum(rate_p_sorted)) ./ (1:K)'); 96 | 97 | c = max(y - rate_p, 0); 98 | 99 | if y > max_mmf_rate 100 | max_mmf_rate = y; 101 | corresponding_f = f; 102 | end 103 | 104 | end 105 | 106 | f = corresponding_f; 107 | p_c = f(1:Nt); 108 | 109 | P = reshape(f(Nt+1:end), Nt, K); 110 | 111 | T_k = sum(square_abs(H'*P), 2) + noise; 112 | T_ck = T_k + square_abs(H'*p_c); 113 | 114 | rate_c = log2(T_ck ./ T_k); 115 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 116 | 117 | rate_p_sorted = sort(rate_p, 'ascend'); 118 | x = min(rate_c); 119 | y = min((x+cumsum(rate_p_sorted)) ./ (1:K)'); 120 | c = max(y - rate_p, 0); 121 | mmf_rate = y; 122 | -------------------------------------------------------------------------------- /Figure1/one_and_one/GPI/gpi_method.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/GPI/gpi_method.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/GPI/gpi_method_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | tolerance = 1e-3; 9 | 10 | gpi_method_time_list = []; 11 | gpi_method_mmf_rate_list = []; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | gpi_method_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, ~, mmf_rate] = gpi_method(H, Pt, tolerance); 23 | gpi_method_mmf_rate = gpi_method_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | gpi_method_time_list = [gpi_method_time_list, time / channel_num]; 29 | gpi_method_mmf_rate_list = [gpi_method_mmf_rate_list, gpi_method_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'gpi_method.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'gpi_method_time_list', ... 41 | 'gpi_method_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_one/low_complexity/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/low_complexity/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/low_complexity/lowComplexity.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate and power allocatoin 2 | % H is channel matrix 3 | % P is power constraint 4 | 5 | function [t, rate] = lowComplexity(H, P) 6 | 7 | if H(:, 1)'*H(:, 1) < H(:, 2)'*H(:, 2) 8 | H = H(:, [2, 1]); 9 | end 10 | 11 | H_bar = zeros(size(H)); 12 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 13 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 14 | 15 | rho = 1 - abs(H_bar(:, 1)' * H_bar(:, 2)) ^ 2; 16 | 17 | coefficient = 1 / sqrt(2*(1 + abs(H_bar(:, 1)'*H_bar(:, 2)))); 18 | pc_bar = coefficient * (H_bar(:, 1) + H_bar(:, 2)*exp(-1i*angle(H_bar(:, 1)'*H_bar(:, 2)))); 19 | 20 | rho1 = H(:, 1)' * H(:, 1) * rho; 21 | rho2 = H(:, 2)' * H(:, 2) * rho; 22 | 23 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 24 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 25 | 26 | Gamma = max(1/rho2 - 1/rho1, 0); 27 | 28 | tList = [0, 1]; 29 | 30 | t = Gamma / P; 31 | if t < 1 && t > 0 32 | % t + 0.001 and t - 0.001 are for jump discontinuity 33 | tList = [tList, t, t + 0.001, t - 0.001]; 34 | end 35 | 36 | t = (0.5*rho2*Gamma - rhoc2*P - 1)/(rho2*P - 2*rhoc2*P) - 1/rho1/P - Gamma/P/2; 37 | if t < 1 && t > 0 38 | tList = [tList, t]; 39 | end 40 | 41 | t = rhoc2 / (rho1+rhoc2); 42 | if t < 1 && t > 0 43 | tList = [tList, t]; 44 | end 45 | 46 | t = (2*rhoc2*P - rho1*Gamma - rho2*Gamma) / (rho1 - rho2 + 2*rhoc2) / P; 47 | if t < 1 && t > 0 48 | tList = [tList, t]; 49 | end 50 | 51 | rateList = []; 52 | for t = tList 53 | rate = maxMinRate(H, t, P); 54 | rateList = [rateList, rate]; 55 | end 56 | 57 | [rate, optimalIndex] = max(rateList); 58 | t = tList(optimalIndex); 59 | -------------------------------------------------------------------------------- /Figure1/one_and_one/low_complexity/low_complexity.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/low_complexity/low_complexity.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/low_complexity/low_complexity_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | low_complexity_time_list = []; 9 | low_complexity_mmf_rate_list = []; 10 | 11 | for snrdB = snrdB_list 12 | 13 | Pt = 10 ^ (snrdB/10); 14 | low_complexity_mmf_rate = 0; 15 | 16 | tic 17 | for n = 1:channel_num 18 | 19 | H = channel(:, :, n); 20 | [~, mmf_rate] = lowComplexity(H, Pt); 21 | low_complexity_mmf_rate = low_complexity_mmf_rate + mmf_rate; 22 | 23 | end 24 | time = toc; 25 | 26 | low_complexity_time_list = [low_complexity_time_list, time / channel_num]; 27 | low_complexity_mmf_rate_list = [low_complexity_mmf_rate_list, low_complexity_mmf_rate / channel_num]; 28 | 29 | end 30 | 31 | filename = 'low_complexity.mat'; 32 | save(filename, ... 33 | 'K', ... 34 | 'Nt', ... 35 | 'channel_num', ... 36 | 'Sigma', ... 37 | 'snrdB_list', ... 38 | 'low_complexity_time_list', ... 39 | 'low_complexity_mmf_rate_list'); 40 | -------------------------------------------------------------------------------- /Figure1/one_and_one/low_complexity/maxMinRate.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate 2 | % H is channel matrix 3 | % tP is the power of private streams and (1 − t)P is the power of common stream 4 | % P is power constraint 5 | 6 | function rate = maxMinRate(H, t, P) 7 | 8 | % normalized channel vectors 9 | H_bar = zeros(size(H)); 10 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 11 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 12 | 13 | rho = 1 - abs(H_bar(:, 1)'*H_bar(:, 2))^2; 14 | 15 | pc_bar = 1 / sqrt(2 * (1 + abs(H_bar(:, 1)' * H_bar(:, 2)))) * ... 16 | (H_bar(:, 1) + H_bar(:, 2) * exp(-1i * angle(H_bar(:, 1)' * H_bar(:, 2)))); 17 | 18 | rho1 = H(:, 1)' * H(:, 1) * rho; 19 | rho2 = H(:, 2)' * H(:, 2) * rho; 20 | 21 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 22 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 23 | 24 | % Gamma is non-negative mathematically, the max is to correct the computational error 25 | Gamma = max(1/rho2 - 1/rho1, 0); 26 | 27 | if t*P > Gamma 28 | % RSMA, SDMA 29 | P1 = 0.5 * (t*P + Gamma); 30 | P2 = 0.5 * (t*P - Gamma); 31 | Pc = (1-t) * P; 32 | R1 = log2(1 + rho1*P1); 33 | R2 = log2(1 + rho2*P2); 34 | Rc = log2(1 + rhoc1*Pc/(1 + rho1*P1)); 35 | rate = R1 + R2 + Rc - max(R1 - R2 - Rc, 0); 36 | rate = 0.5 * rate; 37 | else 38 | P1 = t * P; 39 | Pc = (1-t) * P; 40 | if t > 1e-6 41 | % NOMA 42 | rate = log2(1 + min([rho1 * P1, rhoc2 * Pc])); 43 | else 44 | % Multicast 45 | Rc = log2(1 + rhoc2*Pc); 46 | rate = 0.5 * Rc; 47 | end 48 | end -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/multicast/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/multicast/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/multicast/multicast_sca.m: -------------------------------------------------------------------------------- 1 | function [c, pc, MMFrate] = multicast_sca(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt; 6 | 7 | [U, ~, ~] = svd(H); 8 | pcPrevious = U(:, 1) * sqrt(P_c); 9 | 10 | tPrevious = -inf; 11 | 12 | maxIter = 1000; 13 | for iter = 1:maxIter 14 | 15 | [c, t, pc] = multicast_sca_update(H, Pt, pcPrevious); 16 | 17 | fprintf("Multicast | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 18 | 19 | if(abs(t - tPrevious) <= tolerance) 20 | break; 21 | end 22 | 23 | tPrevious = t; 24 | pcPrevious = pc; 25 | end 26 | MMFrate = t; 27 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/multicast/multicast_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/multicast/multicast_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/multicast/multicast_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | multicast_sca_time_list = []; 9 | multicast_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | multicast_mmf_rate = 0; 17 | 18 | tic; 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = multicast_sca(H, Pt, tolerance); 23 | multicast_mmf_rate = multicast_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | multicast_sca_time_list = [multicast_sca_time_list, time / channel_num]; 29 | multicast_sca_mmf_rate_list = [multicast_sca_mmf_rate_list, multicast_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'multicast_sca.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'multicast_sca_time_list', ... 41 | 'multicast_sca_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/multicast/multicast_sca_update.m: -------------------------------------------------------------------------------- 1 | function [c, t, pc] = ... 2 | multicast_sca_update(H, Pt, pcPrevious) 3 | Nt = size(H, 1); 4 | cvx_begin quiet 5 | variable t 6 | variable alphac1 7 | variable alphac2 8 | variable rhoc1 9 | variable rhoc2 10 | variable pc(Nt) complex 11 | variable c(2) 12 | 13 | maximize(t) 14 | subject to 15 | t <= c(1) 16 | t <= c(2) 17 | 18 | c(1) + c(2) <= alphac1 19 | c(1) + c(2) <= alphac2 20 | 21 | alphac1 <= log(1 + rhoc1) / log(2) 22 | alphac2 <= log(1 + rhoc2) / log(2) 23 | 24 | rhoc1 <= 2*real(pcPrevious'*H(:, 1)*H(:, 1)'*pc) - ... 25 | abs(H(:, 1)'*pcPrevious)^2 26 | rhoc2 <= 2*real(pcPrevious'*H(:, 2)*H(:, 2)'*pc) - ... 27 | abs(H(:, 2)'*pcPrevious)^2 28 | 29 | pc'*pc <= Pt 30 | 31 | c(1) >= 0 32 | c(2) >= 0 33 | cvx_end 34 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/noma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/noma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/noma/noma_sca.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = noma(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_p = Pt / K; 6 | 7 | P = H ./ vecnorm(H) * sqrt(P_p); 8 | p1Previous = P(:, 1); 9 | p2Previous = P(:, 2); 10 | 11 | betaPrevious = 1 + [abs(H(:, 1)' * p1Previous) ^ 2, ... 12 | abs(H(:, 2)' * p1Previous) ^ 2]; 13 | 14 | tPrevious = -inf; 15 | 16 | maxIter = 1000; 17 | for iter = 1:maxIter 18 | 19 | [t, betaa, ... 20 | p1, p2] = ... 21 | nomaUpdate(H, Pt, betaPrevious, ... 22 | p1Previous, p2Previous); 23 | 24 | fprintf("NOMA | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 25 | 26 | if(abs(t - tPrevious) <= tolerance) 27 | break; 28 | end 29 | 30 | tPrevious = t; 31 | betaPrevious = betaa; 32 | p1Previous = p1; 33 | p2Previous = p2; 34 | end 35 | MMFrate = t; 36 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/noma/noma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/noma/noma_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/noma/noma_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | noma_sca_time_list = []; 9 | noma_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | noma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate1] = noma_sca(H, Pt, tolerance); 23 | [~, ~, mmf_rate2] = noma_sca(H(:, [2, 1]), Pt, tolerance); 24 | noma_mmf_rate = noma_mmf_rate + max(mmf_rate1, mmf_rate2); 25 | 26 | end 27 | time = toc; 28 | 29 | noma_sca_time_list = [noma_sca_time_list, time / channel_num]; 30 | noma_sca_mmf_rate_list = [noma_sca_mmf_rate_list, noma_mmf_rate / channel_num]; 31 | 32 | end 33 | 34 | filename = 'noma_sca.mat'; 35 | save(filename, ... 36 | 'K', ... 37 | 'Nt', ... 38 | 'channel_num', ... 39 | 'Sigma', ... 40 | 'snrdB_list', ... 41 | 'noma_sca_time_list', ... 42 | 'noma_sca_mmf_rate_list'); 43 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/noma/noma_sca_update.m: -------------------------------------------------------------------------------- 1 | function [t, betaa, ... 2 | p1, p2] = ... 3 | noma_sca_update(H, Pt, betaPrevious, ... 4 | p1Previous, p2Previous) 5 | Nt = size(H, 1); 6 | cvx_begin quiet 7 | variable t 8 | variable alpha1 9 | variable alpha2 10 | variable beta12 11 | variable beta22 12 | variable rho1 13 | variable rho12 14 | variable rho22 15 | variable p1(Nt) complex 16 | variable p2(Nt) complex 17 | 18 | maximize(t) 19 | subject to 20 | 21 | t <= alpha1 22 | t <= alpha2 23 | 24 | alpha1 <= log(1 + rho1) / log(2) 25 | alpha2 <= log(1 + rho12) / log(2) 26 | alpha2 <= log(1 + rho22) / log(2) 27 | 28 | rho1 <= 2 * real(p1Previous' * H(:, 1) * H(:, 1)' * p1) - ... 29 | abs(H(:, 1)' * p1Previous) ^ 2 30 | 31 | 2 * real(p2Previous' * H(:, 1) * H(:, 1)' * p2) / ... 32 | betaPrevious(1) - ... 33 | square_abs(H(:, 1)' * p2Previous / ... 34 | betaPrevious(1)) * beta12 >= rho12 35 | 2 * real(p2Previous' * H(:, 2) * H(:, 2)' * p2) / ... 36 | betaPrevious(2) - ... 37 | square_abs(H(:, 2)' * p2Previous / ... 38 | betaPrevious(2)) * beta22 >= rho22 39 | 40 | beta12 >= square_abs(H(:, 1)' * p1) + 1 41 | beta22 >= square_abs(H(:, 2)' * p1) + 1 42 | 43 | p1' * p1 + p2' * p2 <= Pt 44 | cvx_end 45 | 46 | betaa = [beta12, beta22]; 47 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/rsma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/rsma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/rsma/rsma_sca.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, pc, c, MMFrate] = rsma_sca(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt * 0.5; 6 | P_p = (Pt-P_c) / K; 7 | 8 | [U, ~, ~] = svd(H); 9 | pcPrevious = U(:, 1) * sqrt(P_c); 10 | P = H ./ vecnorm(H) * sqrt(P_p); 11 | p1Previous = P(:, 1); 12 | p2Previous = P(:, 2); 13 | 14 | betaPrevious = 1 + [abs(H(:, 1)' * p2Previous) ^ 2, ... 15 | abs(H(:, 2)' * p1Previous) ^ 2]; 16 | betacPrevious = 1 + [abs(H(:, 1)' * p1Previous) ^ 2 + ... 17 | abs(H(:, 1)' * p2Previous) ^ 2, ... 18 | abs(H(:, 2)' * p1Previous) ^ 2 + ... 19 | abs(H(:, 2)' * p2Previous) ^ 2]; 20 | 21 | tPrevious = -inf; 22 | 23 | maxIter = 1000; 24 | for iter = 1:maxIter 25 | 26 | [c, t, ... 27 | betaa, betac, ... 28 | p1, p2, pc] = ... 29 | rsma_sca_update(H, Pt, ... 30 | betaPrevious, betacPrevious, ... 31 | p1Previous, p2Previous, pcPrevious); 32 | 33 | fprintf("RSMA | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 34 | 35 | if(abs(t - tPrevious) <= tolerance) 36 | break; 37 | end 38 | 39 | tPrevious = t; 40 | betaPrevious = betaa; 41 | betacPrevious = betac; 42 | p1Previous = p1; 43 | p2Previous = p2; 44 | pcPrevious = pc; 45 | end 46 | MMFrate = t; 47 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/rsma/rsma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/rsma/rsma_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/rsma/rsma_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | rsma_sca_time_list = []; 9 | rsma_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | rsma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, ~, ~, mmf_rate] = rsma_sca(H, Pt, tolerance); 23 | rsma_mmf_rate = rsma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | rsma_sca_time_list = [rsma_sca_time_list, time / channel_num]; 29 | rsma_sca_mmf_rate_list = [rsma_sca_mmf_rate_list, rsma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'rsma_sca.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'rsma_sca_time_list', ... 41 | 'rsma_sca_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/rsma/rsma_sca_update.m: -------------------------------------------------------------------------------- 1 | function [c, t, ... 2 | betaa, betac, ... 3 | p1, p2, pc] = ... 4 | rsma_sca_update(H, Pt, ... 5 | betaPrevious, betacPrevious, ... 6 | p1Previous, p2Previous, pcPrevious) 7 | Nt = size(H, 1); 8 | cvx_begin quiet 9 | variable t 10 | variable alpha1 11 | variable alpha2 12 | variable alphac1 13 | variable alphac2 14 | variable beta1 15 | variable beta2 16 | variable betac1 17 | variable betac2 18 | variable rho1 19 | variable rho2 20 | variable rhoc1 21 | variable rhoc2 22 | variable p1(Nt) complex 23 | variable p2(Nt) complex 24 | variable pc(Nt) complex 25 | variable c(2) 26 | 27 | maximize(t) 28 | subject to 29 | 30 | c(1) >= 0 31 | c(2) >= 0 32 | 33 | c(1) + c(2) <= alphac1 34 | c(1) + c(2) <= alphac2 35 | 36 | t <= alpha1 + c(1) 37 | t <= alpha2 + c(2) 38 | 39 | log(1 + rho1) / log(2) >= alpha1 40 | log(1 + rho2) / log(2) >= alpha2 41 | log(1 + rhoc1) / log(2) >= alphac1 42 | log(1 + rhoc2) / log(2) >= alphac2 43 | 44 | 2 * real(p1Previous' * H(:, 1) * H(:, 1)' * p1) / ... 45 | betaPrevious(1) - ... 46 | square_abs(H(:, 1)' * p1Previous / ... 47 | betaPrevious(1)) * beta1 >= rho1 48 | 2 * real(p2Previous' * H(:, 2) * H(:, 2)' * p2) / ... 49 | betaPrevious(2) - ... 50 | square_abs(H(:, 2)' * p2Previous / ... 51 | betaPrevious(2)) * beta2 >= rho2 52 | 53 | 2 * real(pcPrevious' * H(:, 1) * H(:, 1)' * pc) / ... 54 | betacPrevious(1) - ... 55 | square_abs(H(:, 1)' * pcPrevious / ... 56 | betacPrevious(1)) * betac1 >= rhoc1 57 | 2 * real(pcPrevious' * H(:, 2) * H(:, 2)' * pc) / ... 58 | betacPrevious(2) - ... 59 | square_abs(H(:, 2)' * pcPrevious / ... 60 | betacPrevious(2)) * betac2 >= rhoc2 61 | 62 | beta1 >= square_abs(H(:, 1)' * p2) + 1 63 | beta2 >= square_abs(H(:, 2)' * p1) + 1 64 | 65 | betac1 >= square_abs(H(:, 1)' * p1) + square_abs(H(:, 1)' * p2) + 1 66 | betac2 >= square_abs(H(:, 2)' * p1) + square_abs(H(:, 2)' * p2) + 1 67 | 68 | p1' * p1 + p2' * p2 + pc' * pc <= Pt 69 | cvx_end 70 | 71 | betaa = [beta1, beta2]; 72 | betac = [betac1, betac2]; 73 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/sdma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/sdma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/sdma/sdma_sca.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = sdma_sca(H, Pt, tolerance) 2 | 3 | P = pinv(H'); 4 | p1Previous = sqrt(0.5 * Pt) * P(:, 1) / norm(P(:, 1)); 5 | p2Previous = sqrt(0.5 * Pt) * P(:, 2) / norm(P(:, 2)); 6 | 7 | 8 | betaPrevious = 1 + [abs(H(:, 1)' * p2Previous) ^ 2, ... 9 | abs(H(:, 2)' * p1Previous) ^ 2]; 10 | 11 | tPrevious = -inf; 12 | 13 | maxIter = 1000; 14 | for iter = 1:maxIter 15 | [t, betaa, ... 16 | p1, p2] = ... 17 | sdma_sca_update(H, Pt, betaPrevious, ... 18 | p1Previous, p2Previous); 19 | 20 | fprintf("RSMA | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 21 | 22 | if(abs(t - tPrevious) <= tolerance) 23 | break; 24 | end 25 | 26 | tPrevious = t; 27 | betaPrevious = betaa; 28 | p1Previous = p1; 29 | p2Previous = p2; 30 | end 31 | MMFrate = t; 32 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/sdma/sdma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/sca/sdma/sdma_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/sdma/sdma_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | sdma_sca_time_list = []; 9 | sdma_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | sdma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = sdma_sca(H, Pt, tolerance); 23 | sdma_mmf_rate = sdma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | sdma_sca_time_list = [sdma_sca_time_list, time / channel_num]; 29 | sdma_sca_mmf_rate_list = [sdma_sca_mmf_rate_list, sdma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'sdma_sca.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'sdma_sca_time_list', ... 41 | 'sdma_sca_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_one/sca/sdma/sdma_sca_update.m: -------------------------------------------------------------------------------- 1 | function [t, betaa, ... 2 | p1, p2] = ... 3 | sdma_sca_update(H, Pt, betaPrevious, ... 4 | p1Previous, p2Previous) 5 | Nt = size(H, 1); 6 | cvx_begin quiet 7 | variable t 8 | variable alpha1 9 | variable alpha2 10 | variable beta1 11 | variable beta2 12 | variable rho1 13 | variable rho2 14 | variable p1(Nt) complex 15 | variable p2(Nt) complex 16 | 17 | maximize(t) 18 | subject to 19 | t <= alpha1 20 | t <= alpha2 21 | 22 | log(1 + rho1) / log(2) >= alpha1 23 | log(1 + rho2) / log(2) >= alpha2 24 | 25 | 2 * real(p1Previous' * H(:, 1) * H(:, 1)' * p1) / ... 26 | betaPrevious(1) - ... 27 | square_abs(H(:, 1)' * p1Previous / ... 28 | betaPrevious(1)) * beta1 >= rho1 29 | 2 * real(p2Previous' * H(:, 2) * H(:, 2)' * p2) / ... 30 | betaPrevious(2) - ... 31 | square_abs(H(:, 2)' * p2Previous / ... 32 | betaPrevious(2)) * beta2 >= rho2 33 | 34 | beta1 >= square_abs(H(:, 1)' * p2) + 1 35 | beta2 >= square_abs(H(:, 2)' * p1) + 1 36 | 37 | p1' * p1 + p2' * p2 <= Pt 38 | cvx_end 39 | 40 | betaa = [beta1, beta2]; 41 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/multicast/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/multicast/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/multicast/multicast_wmmse.m: -------------------------------------------------------------------------------- 1 | function [pc, c, MMFrate] = multicast_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt; 6 | 7 | [U, ~, ~] = svd(H); 8 | pc = U(:, 1) * sqrt(P_c); 9 | 10 | MMFrate_last = -inf; 11 | maxIter = 1000; 12 | 13 | for n = 1:maxIter 14 | 15 | T_c1 = square_abs(H(:, 1)'*pc) + 1; 16 | T_c2 = square_abs(H(:, 2)'*pc) + 1; 17 | 18 | g_ck = zeros(K, 1); 19 | g_ck(1) = pc' * H(:, 1) / T_c1; 20 | g_ck(2) = pc' * H(:, 2) / T_c2; 21 | 22 | u_ck = zeros(K, 1); 23 | u_ck(1) = T_c1 / log(2); 24 | u_ck(2) = T_c2 / log(2); 25 | 26 | [pc, c, MMFrate] = multicast_wmmse_update(H, Pt, g_ck, u_ck); 27 | 28 | fprintf("Multicast | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 29 | 30 | if abs(MMFrate - MMFrate_last) <= tolerance 31 | break; 32 | end 33 | MMFrate_last = MMFrate; 34 | 35 | end 36 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/multicast/multicast_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/multicast/multicast_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/multicast/multicast_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | multicast_wmmse_time_list = []; 9 | multicast_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | multicast_mmf_rate = 0; 17 | 18 | tic; 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = multicast_wmmse(H, Pt, tolerance); 23 | multicast_mmf_rate = multicast_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | multicast_wmmse_time_list = [multicast_wmmse_time_list, time / channel_num]; 29 | multicast_wmmse_mmf_rate_list = [multicast_wmmse_mmf_rate_list, multicast_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'multicast_wmmse.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'multicast_wmmse_time_list', ... 41 | 'multicast_wmmse_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/multicast/multicast_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [pc, c, MMFrate] = multicast_wmmse_update(H, Pt, g_ck, u_ck) 2 | 3 | [Nt, ~] = size(H); 4 | cvx_begin quiet 5 | variable t 6 | variable x(2) 7 | variable pc(Nt) complex 8 | 9 | T_c1 = square_abs(H(:, 1)'*pc) + 1; 10 | T_c2 = square_abs(H(:, 2)'*pc) + 1; 11 | 12 | epsilon_c1 = square_abs(g_ck(1))*T_c1 - 2*real(g_ck(1)*H(:, 1)'*pc) + 1; 13 | epsilon_c2 = square_abs(g_ck(2))*T_c2 - 2*real(g_ck(2)*H(:, 2)'*pc) + 1; 14 | 15 | xi_c1 = u_ck(1)*epsilon_c1 - log2(u_ck(1)); 16 | xi_c2 = u_ck(2)*epsilon_c2 - log2(u_ck(2)); 17 | 18 | minimise(t) 19 | subject to 20 | t >= x(1) 21 | t >= x(2) 22 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c1 23 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c2 24 | pc'*pc <= Pt 25 | x <= 0 26 | 27 | cvx_end 28 | 29 | MMFrate = - t; 30 | c = -x; 31 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/noma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/noma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/noma/noma_wmmse.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = noma_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_p = Pt / K; 6 | 7 | P = H ./ vecnorm(H) * sqrt(P_p); 8 | p1 = P(:, 1); 9 | p2 = P(:, 2); 10 | 11 | MMFrate_last = -inf; 12 | maxIter = 1000; 13 | 14 | for n = 1:maxIter 15 | 16 | T_11 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 17 | T_21 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 18 | T_22 = square_abs(H(:, 2)'*p2) + 1; 19 | 20 | g_11 = p1' * H(:, 1) / T_11; 21 | g_21 = p1' * H(:, 2) / T_21; 22 | g_22 = p2' * H(:, 2) / T_22; 23 | 24 | u_11 = T_11 / (T_11 - square_abs(H(:, 1)'*p1)) / log(2); 25 | u_21 = T_21 / T_22 / log(2); 26 | u_22 = T_22 / log(2); 27 | 28 | [p1, p2, MMFrate] = noma_wmmse_update(H, Pt, g_11, g_21, g_22, u_11, u_21, u_22); 29 | 30 | fprintf("NOMA | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 31 | 32 | if abs(MMFrate - MMFrate_last) <= tolerance 33 | break; 34 | end 35 | MMFrate_last = MMFrate; 36 | 37 | end 38 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/noma/noma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/noma/noma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/noma/noma_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | noma_wmmse_time_list = []; 9 | noma_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | noma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate1] = noma_wmmse(H, Pt, tolerance); 23 | [~, ~, mmf_rate2] = noma_wmmse(H(:, [2, 1]), Pt, tolerance); 24 | noma_mmf_rate = noma_mmf_rate + max(mmf_rate1, mmf_rate2); 25 | 26 | end 27 | time = toc; 28 | 29 | noma_wmmse_time_list = [noma_wmmse_time_list, time / channel_num]; 30 | noma_wmmse_mmf_rate_list = [noma_wmmse_mmf_rate_list, noma_mmf_rate / channel_num]; 31 | 32 | end 33 | 34 | filename = 'noma_wmmse.mat'; 35 | save(filename, ... 36 | 'K', ... 37 | 'Nt', ... 38 | 'channel_num', ... 39 | 'Sigma', ... 40 | 'snrdB_list', ... 41 | 'noma_wmmse_time_list', ... 42 | 'noma_wmmse_mmf_rate_list'); 43 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/noma/noma_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = noma_wmmse_update(H, Pt, g_11, g_21, g_22, u_11, u_21, u_22) 2 | 3 | [Nt, K] = size(H); 4 | 5 | cvx_begin quiet 6 | 7 | variable t 8 | variable p1(Nt) complex 9 | variable p2(Nt) complex 10 | 11 | T_11 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 12 | T_21 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 13 | T_22 = square_abs(H(:, 2)'*p2) + 1; 14 | 15 | epsilon_11 = square_abs(g_11)*T_11 - 2*real(g_11*H(:, 1)'*p1) + 1; 16 | epsilon_21 = square_abs(g_21)*T_21 - 2*real(g_21*H(:, 2)'*p1) + 1; 17 | epsilon_22 = square_abs(g_22)*T_22 - 2*real(g_22*H(:, 2)'*p2) + 1; 18 | 19 | xi_11 = u_11*epsilon_11 - log2(u_11); 20 | xi_21 = u_21*epsilon_21 - log2(u_21); 21 | xi_22 = u_22*epsilon_22 - log2(u_22); 22 | 23 | minimise(t) 24 | subject to 25 | t >= xi_11 26 | t >= xi_21 27 | t >= xi_22 28 | p1'*p1 + p2'*p2 <= Pt 29 | 30 | cvx_end 31 | 32 | MMFrate = 1/log(2) + log2(log(2)) - t; 33 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/rsma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/rsma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/rsma/rsma_wmmse.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, pc, c, MMFrate] = rsma_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt * 0.5; 6 | P_p = (Pt-P_c) / K; 7 | 8 | [U, ~, ~] = svd(H); 9 | pc = U(:, 1) * sqrt(P_c); 10 | P = H ./ vecnorm(H) * sqrt(P_p); 11 | p1 = P(:, 1); 12 | p2 = P(:, 2); 13 | 14 | MMFrate_last = -inf; 15 | maxIter = 1000; 16 | 17 | for n = 1:maxIter 18 | 19 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 20 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 21 | 22 | g_k = zeros(K, 1); 23 | g_k(1) = p1' * H(:, 1) / T_1; 24 | g_k(2) = p2' * H(:, 2) / T_2; 25 | 26 | u_k = zeros(K, 1); 27 | u_k(1) = T_1 / (T_1 - square_abs(H(:, 1)'*p1)) / log(2); 28 | u_k(2) = T_2 / (T_2 - square_abs(H(:, 2)'*p2)) / log(2); 29 | 30 | T_c1 = square_abs(H(:, 1)'*pc) + square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 31 | T_c2 = square_abs(H(:, 2)'*pc) + square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 32 | 33 | g_ck = zeros(K, 1); 34 | g_ck(1) = pc' * H(:, 1) / T_c1; 35 | g_ck(2) = pc' * H(:, 2) / T_c2; 36 | 37 | u_ck = zeros(K, 1); 38 | u_ck(1) = T_c1 / T_1 / log(2); 39 | u_ck(2) = T_c2 / T_2 / log(2); 40 | 41 | [p1, p2, pc, c, MMFrate] = rsma_wmmse_update(H, Pt, g_ck, g_k, u_ck, u_k); 42 | 43 | fprintf("RSMA | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 44 | 45 | if abs(MMFrate - MMFrate_last) <= tolerance 46 | break; 47 | end 48 | MMFrate_last = MMFrate; 49 | 50 | end 51 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/rsma/rsma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/rsma/rsma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/rsma/rsma_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | rsma_wmmse_time_list = []; 9 | rsma_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | rsma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, ~, ~, mmf_rate] = rsma_wmmse(H, Pt, tolerance); 23 | rsma_mmf_rate = rsma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | rsma_wmmse_time_list = [rsma_wmmse_time_list, time / channel_num]; 29 | rsma_wmmse_mmf_rate_list = [rsma_wmmse_mmf_rate_list, rsma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'rsma_wmmse.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'rsma_wmmse_time_list', ... 41 | 'rsma_wmmse_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/rsma/rsma_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, pc, c, MMFrate] = rsma_wmmse_update(H, Pt, g_ck, g_k, u_ck, u_k) 2 | 3 | [Nt, ~] = size(H); 4 | cvx_begin quiet 5 | variable t 6 | variable x(2) 7 | variable p1(Nt) complex 8 | variable p2(Nt) complex 9 | variable pc(Nt) complex 10 | 11 | T_c1 = square_abs(H(:, 1)'*pc) + square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 12 | T_c2 = square_abs(H(:, 2)'*pc) + square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 13 | 14 | epsilon_c1 = square_abs(g_ck(1))*T_c1 - 2*real(g_ck(1)*H(:, 1)'*pc) + 1; 15 | epsilon_c2 = square_abs(g_ck(2))*T_c2 - 2*real(g_ck(2)*H(:, 2)'*pc) + 1; 16 | 17 | xi_c1 = u_ck(1)*epsilon_c1 - log2(u_ck(1)); 18 | xi_c2 = u_ck(2)*epsilon_c2 - log2(u_ck(2)); 19 | 20 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 21 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 22 | 23 | epsilon_1 = square_abs(g_k(1))*T_1 - 2*real(g_k(1)*H(:, 1)'*p1) + 1; 24 | epsilon_2 = square_abs(g_k(2))*T_2 - 2*real(g_k(2)*H(:, 2)'*p2) + 1; 25 | 26 | xi_1 = u_k(1)*epsilon_1 - log2(u_k(1)); 27 | xi_2 = u_k(2)*epsilon_2 - log2(u_k(2)); 28 | 29 | minimise(t) 30 | subject to 31 | t >= xi_1 + x(1) 32 | t >= xi_2 + x(2) 33 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c1 34 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c2 35 | p1'*p1 + p2'*p2 + pc'*pc <= Pt 36 | x <= 0 37 | 38 | cvx_end 39 | 40 | MMFrate = 1/log(2) + log2(log(2)) - t; 41 | c = -x; -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/sdma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/sdma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/sdma/sdma_wmmse.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = sdma_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_p = Pt / K; 6 | 7 | P = H ./ vecnorm(H) * sqrt(P_p); 8 | p1 = P(:, 1); 9 | p2 = P(:, 2); 10 | 11 | MMFrate_last = -inf; 12 | maxIter = 1000; 13 | 14 | for n = 1:maxIter 15 | 16 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 17 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 18 | 19 | g_k = zeros(K, 1); 20 | g_k(1) = p1' * H(:, 1) / T_1; 21 | g_k(2) = p2' * H(:, 2) / T_2; 22 | 23 | u_k = zeros(K, 1); 24 | u_k(1) = T_1 / (T_1 - square_abs(H(:, 1)'*p1)) / log(2); 25 | u_k(2) = T_2 / (T_2 - square_abs(H(:, 2)'*p2)) / log(2); 26 | 27 | [p1, p2, MMFrate] = sdma_wmmse_update(H, Pt, g_k, u_k); 28 | 29 | fprintf("SDMA | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 30 | 31 | if abs(MMFrate - MMFrate_last) <= tolerance 32 | break; 33 | end 34 | MMFrate_last = MMFrate; 35 | 36 | end 37 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/sdma/sdma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_one/wmmse/sdma/sdma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/sdma/sdma_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | sdma_wmmse_time_list = []; 9 | sdma_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | sdma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = sdma_wmmse(H, Pt, tolerance); 23 | sdma_mmf_rate = sdma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | sdma_wmmse_time_list = [sdma_wmmse_time_list, time / channel_num]; 29 | sdma_wmmse_mmf_rate_list = [sdma_wmmse_mmf_rate_list, sdma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'sdma_wmmse.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'sdma_wmmse_time_list', ... 41 | 'sdma_wmmse_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_one/wmmse/sdma/sdma_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = sdma_wmmse_update(H, Pt, g_k, u_k) 2 | 3 | [Nt, ~] = size(H); 4 | cvx_begin quiet 5 | variable t 6 | variable p1(Nt) complex 7 | variable p2(Nt) complex 8 | 9 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 10 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 11 | 12 | epsilon_1 = square_abs(g_k(1))*T_1 - 2*real(g_k(1)*H(:, 1)'*p1) + 1; 13 | epsilon_2 = square_abs(g_k(2))*T_2 - 2*real(g_k(2)*H(:, 2)'*p2) + 1; 14 | 15 | xi_1 = u_k(1)*epsilon_1 - log2(u_k(1)); 16 | xi_2 = u_k(2)*epsilon_2 - log2(u_k(2)); 17 | 18 | minimise(t) 19 | subject to 20 | t >= xi_1 21 | t >= xi_2 22 | p1'*p1 + p2'*p2 <= Pt 23 | 24 | cvx_end 25 | 26 | MMFrate = 1/log(2) + log2(log(2)) - t; 27 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/GPI_method/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/GPI_method/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/GPI_method/gpi_method.m: -------------------------------------------------------------------------------- 1 | function [P, p_c, c, mmf_rate] = gpi_method(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | noise = ones(K, 1); 6 | 7 | P_c = Pt * 0.5; 8 | P_p = (Pt-P_c) / K; 9 | 10 | [U, ~, ~] = svd(H); 11 | p_c = U(:,1) * sqrt(P_c); 12 | P = H ./ vecnorm(H) * sqrt(P_p); 13 | 14 | gamma_min = 0; 15 | gamma_max = 100; 16 | gamma_num = 1001; 17 | 18 | alpha = 0.1; 19 | 20 | T_k = sum(square_abs(H'*P), 2) + noise; 21 | T_ck = T_k + square_abs(H'*p_c); 22 | 23 | rate_c = log2(T_ck ./ T_k); 24 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 25 | 26 | rate_p_sorted = sort(rate_p, 'ascend'); 27 | x = min(rate_c); 28 | y = min((x+cumsum(rate_p_sorted)) ./ (1:K)'); 29 | 30 | max_mmf_rate = y; 31 | corresponding_f = [p_c; reshape(P, K*Nt, 1)]; 32 | 33 | f = corresponding_f; 34 | c = max(y - rate_p, 0); 35 | f_last = f; 36 | 37 | for gamma = linspace(gamma_min, gamma_max, gamma_num) 38 | 39 | for n = 1:1000 40 | 41 | A = zeros(Nt*(K+1), Nt*(K+1), K); 42 | B = zeros(Nt*(K+1)); 43 | C = zeros(Nt*(K+1)); 44 | D = zeros(Nt*(K+1)); 45 | 46 | for k = 1:K 47 | A_k = zeros(Nt); 48 | for m = 1:K 49 | A_k = blkdiag(A_k, H(:, k)*H(:, k)'); 50 | end 51 | A(:, :, k) = A_k + eye(Nt*(K+1))/Pt; 52 | B(:, :, k) = A(:, :, k) - blkdiag(zeros(Nt*k), H(:, k)*H(:, k)', zeros(Nt*(K-k))); 53 | C(:, :, k) = A(:, :, k) + blkdiag(H(:, k)*H(:, k)', zeros(Nt*K)); 54 | D(:, :, k) = A(:, :, k); 55 | end 56 | 57 | T_k = sum(square_abs(H'*P), 2) + noise; 58 | T_ck = T_k + square_abs(H'*p_c); 59 | 60 | rate_c = log2(T_ck ./ T_k); 61 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 62 | 63 | ratio_c = exp(-1/alpha*(rate_c)) / sum(exp(-1/alpha*(rate_c))); 64 | ratio_t = exp(-1/alpha*(c+rate_p)) / sum(exp(-1/alpha*(c+rate_p))); 65 | 66 | E = zeros(Nt*(K+1)); 67 | F = zeros(Nt*(K+1)); 68 | for k = 1:K 69 | E = E + ratio_t(k)*A(:, :, k)/(f'*A(:, :, k)*f) + ratio_c(k)*gamma*C(:, :, k)/(f'*C(:, :, k)*f); 70 | F = F + ratio_t(k)*B(:, :, k)/(f'*B(:, :, k)*f) + ratio_c(k)*gamma*D(:, :, k)/(f'*D(:, :, k)*f); 71 | end 72 | 73 | f = F \ (E*f); 74 | f = f / norm(f) * sqrt(Pt); 75 | 76 | e = norm(f - f_last, 'inf'); 77 | if e < tolerance 78 | break; 79 | end 80 | 81 | f_last = f; 82 | end 83 | 84 | p_c = f(1:Nt); 85 | P = reshape(f(Nt+1:end), Nt, K); 86 | 87 | T_k = sum(square_abs(H'*P), 2) + noise; 88 | T_ck = T_k + square_abs(H'*p_c); 89 | 90 | rate_c = log2(T_ck ./ T_k); 91 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 92 | 93 | rate_p_sorted = sort(rate_p, 'ascend'); 94 | x = min(rate_c); 95 | y = min((x+cumsum(rate_p_sorted)) ./ (1:K)'); 96 | 97 | c = max(y - rate_p, 0); 98 | 99 | if y > max_mmf_rate 100 | max_mmf_rate = y; 101 | corresponding_f = f; 102 | end 103 | 104 | end 105 | 106 | f = corresponding_f; 107 | p_c = f(1:Nt); 108 | 109 | P = reshape(f(Nt+1:end), Nt, K); 110 | 111 | T_k = sum(square_abs(H'*P), 2) + noise; 112 | T_ck = T_k + square_abs(H'*p_c); 113 | 114 | rate_c = log2(T_ck ./ T_k); 115 | rate_p = log2(T_k ./ (T_k-square_abs(diag(H'*P)))); 116 | 117 | rate_p_sorted = sort(rate_p, 'ascend'); 118 | x = min(rate_c); 119 | y = min((x+cumsum(rate_p_sorted)) ./ (1:K)'); 120 | c = max(y - rate_p, 0); 121 | mmf_rate = y; 122 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/GPI_method/gpi_method.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/GPI_method/gpi_method.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/GPI_method/gpi_method_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | tolerance = 1e-3; 9 | 10 | gpi_method_time_list = []; 11 | gpi_method_mmf_rate_list = []; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | gpi_method_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, ~, mmf_rate] = gpi_method(H, Pt, tolerance); 23 | gpi_method_mmf_rate = gpi_method_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | gpi_method_time_list = [gpi_method_time_list, time / channel_num]; 29 | gpi_method_mmf_rate_list = [gpi_method_mmf_rate_list, gpi_method_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'gpi_method.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'gpi_method_time_list', ... 41 | 'gpi_method_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/low_complexity/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/low_complexity/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/low_complexity/lowComplexity.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate and power allocatoin 2 | % H is channel matrix 3 | % P is power constraint 4 | 5 | function [t, rate] = lowComplexity(H, P) 6 | 7 | if H(:, 1)'*H(:, 1) < H(:, 2)'*H(:, 2) 8 | H = H(:, [2, 1]); 9 | end 10 | 11 | H_bar = zeros(size(H)); 12 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 13 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 14 | 15 | rho = 1 - abs(H_bar(:, 1)' * H_bar(:, 2)) ^ 2; 16 | 17 | coefficient = 1 / sqrt(2*(1 + abs(H_bar(:, 1)'*H_bar(:, 2)))); 18 | pc_bar = coefficient * (H_bar(:, 1) + H_bar(:, 2)*exp(-1i*angle(H_bar(:, 1)'*H_bar(:, 2)))); 19 | 20 | rho1 = H(:, 1)' * H(:, 1) * rho; 21 | rho2 = H(:, 2)' * H(:, 2) * rho; 22 | 23 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 24 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 25 | 26 | Gamma = max(1/rho2 - 1/rho1, 0); 27 | 28 | tList = [0, 1]; 29 | 30 | t = Gamma / P; 31 | if t < 1 && t > 0 32 | % t + 0.001 and t - 0.001 are for jump discontinuity 33 | tList = [tList, t, t + 0.001, t - 0.001]; 34 | end 35 | 36 | t = (0.5*rho2*Gamma - rhoc2*P - 1)/(rho2*P - 2*rhoc2*P) - 1/rho1/P - Gamma/P/2; 37 | if t < 1 && t > 0 38 | tList = [tList, t]; 39 | end 40 | 41 | t = rhoc2 / (rho1+rhoc2); 42 | if t < 1 && t > 0 43 | tList = [tList, t]; 44 | end 45 | 46 | t = (2*rhoc2*P - rho1*Gamma - rho2*Gamma) / (rho1 - rho2 + 2*rhoc2) / P; 47 | if t < 1 && t > 0 48 | tList = [tList, t]; 49 | end 50 | 51 | rateList = []; 52 | for t = tList 53 | rate = maxMinRate(H, t, P); 54 | rateList = [rateList, rate]; 55 | end 56 | 57 | [rate, optimalIndex] = max(rateList); 58 | t = tList(optimalIndex); 59 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/low_complexity/low_complexity.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/low_complexity/low_complexity.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/low_complexity/low_complexity_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | low_complexity_time_list = []; 9 | low_complexity_mmf_rate_list = []; 10 | 11 | for snrdB = snrdB_list 12 | 13 | Pt = 10 ^ (snrdB/10); 14 | low_complexity_mmf_rate = 0; 15 | 16 | tic 17 | for n = 1:channel_num 18 | 19 | H = channel(:, :, n); 20 | [~, mmf_rate] = lowComplexity(H, Pt); 21 | low_complexity_mmf_rate = low_complexity_mmf_rate + mmf_rate; 22 | 23 | end 24 | time = toc; 25 | 26 | low_complexity_time_list = [low_complexity_time_list, time / channel_num]; 27 | low_complexity_mmf_rate_list = [low_complexity_mmf_rate_list, low_complexity_mmf_rate / channel_num]; 28 | 29 | end 30 | 31 | filename = 'low_complexity.mat'; 32 | save(filename, ... 33 | 'K', ... 34 | 'Nt', ... 35 | 'channel_num', ... 36 | 'Sigma', ... 37 | 'snrdB_list', ... 38 | 'low_complexity_time_list', ... 39 | 'low_complexity_mmf_rate_list'); 40 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/low_complexity/maxMinRate.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate 2 | % H is channel matrix 3 | % tP is the power of private streams and (1 − t)P is the power of common stream 4 | % P is power constraint 5 | 6 | function rate = maxMinRate(H, t, P) 7 | 8 | % normalized channel vectors 9 | H_bar = zeros(size(H)); 10 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 11 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 12 | 13 | rho = 1 - abs(H_bar(:, 1)'*H_bar(:, 2))^2; 14 | 15 | pc_bar = 1 / sqrt(2 * (1 + abs(H_bar(:, 1)' * H_bar(:, 2)))) * ... 16 | (H_bar(:, 1) + H_bar(:, 2) * exp(-1i * angle(H_bar(:, 1)' * H_bar(:, 2)))); 17 | 18 | rho1 = H(:, 1)' * H(:, 1) * rho; 19 | rho2 = H(:, 2)' * H(:, 2) * rho; 20 | 21 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 22 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 23 | 24 | % Gamma is non-negative mathematically, the max is to correct the computational error 25 | Gamma = max(1/rho2 - 1/rho1, 0); 26 | 27 | if t*P > Gamma 28 | % RSMA, SDMA 29 | P1 = 0.5 * (t*P + Gamma); 30 | P2 = 0.5 * (t*P - Gamma); 31 | Pc = (1-t) * P; 32 | R1 = log2(1 + rho1*P1); 33 | R2 = log2(1 + rho2*P2); 34 | Rc = log2(1 + rhoc1*Pc/(1 + rho1*P1)); 35 | rate = R1 + R2 + Rc - max(R1 - R2 - Rc, 0); 36 | rate = 0.5 * rate; 37 | else 38 | P1 = t * P; 39 | Pc = (1-t) * P; 40 | if t > 1e-6 41 | % NOMA 42 | rate = log2(1 + min([rho1 * P1, rhoc2 * Pc])); 43 | else 44 | % Multicast 45 | Rc = log2(1 + rhoc2*Pc); 46 | rate = 0.5 * Rc; 47 | end 48 | end -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/multicast/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/multicast/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/multicast/multicast_sca.m: -------------------------------------------------------------------------------- 1 | function [c, pc, MMFrate] = multicast_sca(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt; 6 | 7 | [U, ~, ~] = svd(H); 8 | pcPrevious = U(:, 1) * sqrt(P_c); 9 | 10 | tPrevious = -inf; 11 | 12 | maxIter = 1000; 13 | for iter = 1:maxIter 14 | 15 | [c, t, pc] = multicast_sca_update(H, Pt, pcPrevious); 16 | 17 | fprintf("Multicast | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 18 | 19 | if(abs(t - tPrevious) <= tolerance) 20 | break; 21 | end 22 | 23 | tPrevious = t; 24 | pcPrevious = pc; 25 | end 26 | MMFrate = t; 27 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/multicast/multicast_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/multicast/multicast_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/multicast/multicast_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | multicast_sca_time_list = []; 9 | multicast_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | multicast_mmf_rate = 0; 17 | 18 | tic; 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = multicast_sca(H, Pt, tolerance); 23 | multicast_mmf_rate = multicast_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | multicast_sca_time_list = [multicast_sca_time_list, time / channel_num]; 29 | multicast_sca_mmf_rate_list = [multicast_sca_mmf_rate_list, multicast_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'multicast_sca.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'multicast_sca_time_list', ... 41 | 'multicast_sca_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/multicast/multicast_sca_update.m: -------------------------------------------------------------------------------- 1 | function [c, t, pc] = ... 2 | multicast_sca_update(H, Pt, pcPrevious) 3 | Nt = size(H, 1); 4 | cvx_begin quiet 5 | variable t 6 | variable alphac1 7 | variable alphac2 8 | variable rhoc1 9 | variable rhoc2 10 | variable pc(Nt) complex 11 | variable c(2) 12 | 13 | maximize(t) 14 | subject to 15 | t <= c(1) 16 | t <= c(2) 17 | 18 | c(1) + c(2) <= alphac1 19 | c(1) + c(2) <= alphac2 20 | 21 | alphac1 <= log(1 + rhoc1) / log(2) 22 | alphac2 <= log(1 + rhoc2) / log(2) 23 | 24 | rhoc1 <= 2*real(pcPrevious'*H(:, 1)*H(:, 1)'*pc) - ... 25 | abs(H(:, 1)'*pcPrevious)^2 26 | rhoc2 <= 2*real(pcPrevious'*H(:, 2)*H(:, 2)'*pc) - ... 27 | abs(H(:, 2)'*pcPrevious)^2 28 | 29 | pc'*pc <= Pt 30 | 31 | c(1) >= 0 32 | c(2) >= 0 33 | cvx_end 34 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/noma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/noma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/noma/noma_sca.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = noma(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_p = Pt / K; 6 | 7 | P = H ./ vecnorm(H) * sqrt(P_p); 8 | p1Previous = P(:, 1); 9 | p2Previous = P(:, 2); 10 | 11 | betaPrevious = 1 + [abs(H(:, 1)' * p1Previous) ^ 2, ... 12 | abs(H(:, 2)' * p1Previous) ^ 2]; 13 | 14 | tPrevious = -inf; 15 | 16 | maxIter = 1000; 17 | for iter = 1:maxIter 18 | 19 | [t, betaa, ... 20 | p1, p2] = ... 21 | nomaUpdate(H, Pt, betaPrevious, ... 22 | p1Previous, p2Previous); 23 | 24 | fprintf("NOMA | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 25 | 26 | if(abs(t - tPrevious) <= tolerance) 27 | break; 28 | end 29 | 30 | tPrevious = t; 31 | betaPrevious = betaa; 32 | p1Previous = p1; 33 | p2Previous = p2; 34 | end 35 | MMFrate = t; 36 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/noma/noma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/noma/noma_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/noma/noma_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | noma_sca_time_list = []; 9 | noma_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | noma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate1] = noma_sca(H, Pt, tolerance); 23 | [~, ~, mmf_rate2] = noma_sca(H(:, [2, 1]), Pt, tolerance); 24 | noma_mmf_rate = noma_mmf_rate + max(mmf_rate1, mmf_rate2); 25 | 26 | end 27 | time = toc; 28 | 29 | noma_sca_time_list = [noma_sca_time_list, time / channel_num]; 30 | noma_sca_mmf_rate_list = [noma_sca_mmf_rate_list, noma_mmf_rate / channel_num]; 31 | 32 | end 33 | 34 | filename = 'noma_sca.mat'; 35 | save(filename, ... 36 | 'K', ... 37 | 'Nt', ... 38 | 'channel_num', ... 39 | 'Sigma', ... 40 | 'snrdB_list', ... 41 | 'noma_sca_time_list', ... 42 | 'noma_sca_mmf_rate_list'); 43 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/noma/noma_sca_update.m: -------------------------------------------------------------------------------- 1 | function [t, betaa, ... 2 | p1, p2] = ... 3 | noma_sca_update(H, Pt, betaPrevious, ... 4 | p1Previous, p2Previous) 5 | Nt = size(H, 1); 6 | cvx_begin quiet 7 | variable t 8 | variable alpha1 9 | variable alpha2 10 | variable beta12 11 | variable beta22 12 | variable rho1 13 | variable rho12 14 | variable rho22 15 | variable p1(Nt) complex 16 | variable p2(Nt) complex 17 | 18 | maximize(t) 19 | subject to 20 | 21 | t <= alpha1 22 | t <= alpha2 23 | 24 | alpha1 <= log(1 + rho1) / log(2) 25 | alpha2 <= log(1 + rho12) / log(2) 26 | alpha2 <= log(1 + rho22) / log(2) 27 | 28 | rho1 <= 2 * real(p1Previous' * H(:, 1) * H(:, 1)' * p1) - ... 29 | abs(H(:, 1)' * p1Previous) ^ 2 30 | 31 | 2 * real(p2Previous' * H(:, 1) * H(:, 1)' * p2) / ... 32 | betaPrevious(1) - ... 33 | square_abs(H(:, 1)' * p2Previous / ... 34 | betaPrevious(1)) * beta12 >= rho12 35 | 2 * real(p2Previous' * H(:, 2) * H(:, 2)' * p2) / ... 36 | betaPrevious(2) - ... 37 | square_abs(H(:, 2)' * p2Previous / ... 38 | betaPrevious(2)) * beta22 >= rho22 39 | 40 | beta12 >= square_abs(H(:, 1)' * p1) + 1 41 | beta22 >= square_abs(H(:, 2)' * p1) + 1 42 | 43 | p1' * p1 + p2' * p2 <= Pt 44 | cvx_end 45 | 46 | betaa = [beta12, beta22]; 47 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/rsma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/rsma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/rsma/rsma_sca.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, pc, c, MMFrate] = rsma_sca(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt * 0.5; 6 | P_p = (Pt-P_c) / K; 7 | 8 | [U, ~, ~] = svd(H); 9 | pcPrevious = U(:, 1) * sqrt(P_c); 10 | P = H ./ vecnorm(H) * sqrt(P_p); 11 | p1Previous = P(:, 1); 12 | p2Previous = P(:, 2); 13 | 14 | betaPrevious = 1 + [abs(H(:, 1)' * p2Previous) ^ 2, ... 15 | abs(H(:, 2)' * p1Previous) ^ 2]; 16 | betacPrevious = 1 + [abs(H(:, 1)' * p1Previous) ^ 2 + ... 17 | abs(H(:, 1)' * p2Previous) ^ 2, ... 18 | abs(H(:, 2)' * p1Previous) ^ 2 + ... 19 | abs(H(:, 2)' * p2Previous) ^ 2]; 20 | 21 | tPrevious = -inf; 22 | 23 | maxIter = 1000; 24 | for iter = 1:maxIter 25 | 26 | [c, t, ... 27 | betaa, betac, ... 28 | p1, p2, pc] = ... 29 | rsma_sca_update(H, Pt, ... 30 | betaPrevious, betacPrevious, ... 31 | p1Previous, p2Previous, pcPrevious); 32 | 33 | fprintf("RSMA | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 34 | 35 | if(abs(t - tPrevious) <= tolerance) 36 | break; 37 | end 38 | 39 | tPrevious = t; 40 | betaPrevious = betaa; 41 | betacPrevious = betac; 42 | p1Previous = p1; 43 | p2Previous = p2; 44 | pcPrevious = pc; 45 | end 46 | MMFrate = t; 47 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/rsma/rsma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/rsma/rsma_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/rsma/rsma_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | rsma_sca_time_list = []; 9 | rsma_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | rsma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, ~, ~, mmf_rate] = rsma_sca(H, Pt, tolerance); 23 | rsma_mmf_rate = rsma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | rsma_sca_time_list = [rsma_sca_time_list, time / channel_num]; 29 | rsma_sca_mmf_rate_list = [rsma_sca_mmf_rate_list, rsma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'rsma_sca.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'rsma_sca_time_list', ... 41 | 'rsma_sca_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/rsma/rsma_sca_update.m: -------------------------------------------------------------------------------- 1 | function [c, t, ... 2 | betaa, betac, ... 3 | p1, p2, pc] = ... 4 | rsma_sca_update(H, Pt, ... 5 | betaPrevious, betacPrevious, ... 6 | p1Previous, p2Previous, pcPrevious) 7 | Nt = size(H, 1); 8 | cvx_begin quiet 9 | variable t 10 | variable alpha1 11 | variable alpha2 12 | variable alphac1 13 | variable alphac2 14 | variable beta1 15 | variable beta2 16 | variable betac1 17 | variable betac2 18 | variable rho1 19 | variable rho2 20 | variable rhoc1 21 | variable rhoc2 22 | variable p1(Nt) complex 23 | variable p2(Nt) complex 24 | variable pc(Nt) complex 25 | variable c(2) 26 | 27 | maximize(t) 28 | subject to 29 | 30 | c(1) >= 0 31 | c(2) >= 0 32 | 33 | c(1) + c(2) <= alphac1 34 | c(1) + c(2) <= alphac2 35 | 36 | t <= alpha1 + c(1) 37 | t <= alpha2 + c(2) 38 | 39 | log(1 + rho1) / log(2) >= alpha1 40 | log(1 + rho2) / log(2) >= alpha2 41 | log(1 + rhoc1) / log(2) >= alphac1 42 | log(1 + rhoc2) / log(2) >= alphac2 43 | 44 | 2 * real(p1Previous' * H(:, 1) * H(:, 1)' * p1) / ... 45 | betaPrevious(1) - ... 46 | square_abs(H(:, 1)' * p1Previous / ... 47 | betaPrevious(1)) * beta1 >= rho1 48 | 2 * real(p2Previous' * H(:, 2) * H(:, 2)' * p2) / ... 49 | betaPrevious(2) - ... 50 | square_abs(H(:, 2)' * p2Previous / ... 51 | betaPrevious(2)) * beta2 >= rho2 52 | 53 | 2 * real(pcPrevious' * H(:, 1) * H(:, 1)' * pc) / ... 54 | betacPrevious(1) - ... 55 | square_abs(H(:, 1)' * pcPrevious / ... 56 | betacPrevious(1)) * betac1 >= rhoc1 57 | 2 * real(pcPrevious' * H(:, 2) * H(:, 2)' * pc) / ... 58 | betacPrevious(2) - ... 59 | square_abs(H(:, 2)' * pcPrevious / ... 60 | betacPrevious(2)) * betac2 >= rhoc2 61 | 62 | beta1 >= square_abs(H(:, 1)' * p2) + 1 63 | beta2 >= square_abs(H(:, 2)' * p1) + 1 64 | 65 | betac1 >= square_abs(H(:, 1)' * p1) + square_abs(H(:, 1)' * p2) + 1 66 | betac2 >= square_abs(H(:, 2)' * p1) + square_abs(H(:, 2)' * p2) + 1 67 | 68 | p1' * p1 + p2' * p2 + pc' * pc <= Pt 69 | cvx_end 70 | 71 | betaa = [beta1, beta2]; 72 | betac = [betac1, betac2]; 73 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/sdma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/sdma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/sdma/sdma_sca.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = sdma_sca(H, Pt, tolerance) 2 | 3 | P = pinv(H'); 4 | p1Previous = sqrt(0.5 * Pt) * P(:, 1) / norm(P(:, 1)); 5 | p2Previous = sqrt(0.5 * Pt) * P(:, 2) / norm(P(:, 2)); 6 | 7 | 8 | betaPrevious = 1 + [abs(H(:, 1)' * p2Previous) ^ 2, ... 9 | abs(H(:, 2)' * p1Previous) ^ 2]; 10 | 11 | tPrevious = -inf; 12 | 13 | maxIter = 1000; 14 | for iter = 1:maxIter 15 | [t, betaa, ... 16 | p1, p2] = ... 17 | sdma_sca_update(H, Pt, betaPrevious, ... 18 | p1Previous, p2Previous); 19 | 20 | fprintf("RSMA | %3d | obj = %f | |obj - obj_last| = %f\n", iter, t, abs(t - tPrevious)); 21 | 22 | if(abs(t - tPrevious) <= tolerance) 23 | break; 24 | end 25 | 26 | tPrevious = t; 27 | betaPrevious = betaa; 28 | p1Previous = p1; 29 | p2Previous = p2; 30 | end 31 | MMFrate = t; 32 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/sdma/sdma_sca.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/sca/sdma/sdma_sca.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/sdma/sdma_sca_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | sdma_sca_time_list = []; 9 | sdma_sca_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | sdma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = sdma_sca(H, Pt, tolerance); 23 | sdma_mmf_rate = sdma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | sdma_sca_time_list = [sdma_sca_time_list, time / channel_num]; 29 | sdma_sca_mmf_rate_list = [sdma_sca_mmf_rate_list, sdma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'sdma_sca.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'sdma_sca_time_list', ... 41 | 'sdma_sca_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/sca/sdma/sdma_sca_update.m: -------------------------------------------------------------------------------- 1 | function [t, betaa, ... 2 | p1, p2] = ... 3 | sdma_sca_update(H, Pt, betaPrevious, ... 4 | p1Previous, p2Previous) 5 | Nt = size(H, 1); 6 | cvx_begin quiet 7 | variable t 8 | variable alpha1 9 | variable alpha2 10 | variable beta1 11 | variable beta2 12 | variable rho1 13 | variable rho2 14 | variable p1(Nt) complex 15 | variable p2(Nt) complex 16 | 17 | maximize(t) 18 | subject to 19 | t <= alpha1 20 | t <= alpha2 21 | 22 | log(1 + rho1) / log(2) >= alpha1 23 | log(1 + rho2) / log(2) >= alpha2 24 | 25 | 2 * real(p1Previous' * H(:, 1) * H(:, 1)' * p1) / ... 26 | betaPrevious(1) - ... 27 | square_abs(H(:, 1)' * p1Previous / ... 28 | betaPrevious(1)) * beta1 >= rho1 29 | 2 * real(p2Previous' * H(:, 2) * H(:, 2)' * p2) / ... 30 | betaPrevious(2) - ... 31 | square_abs(H(:, 2)' * p2Previous / ... 32 | betaPrevious(2)) * beta2 >= rho2 33 | 34 | beta1 >= square_abs(H(:, 1)' * p2) + 1 35 | beta2 >= square_abs(H(:, 2)' * p1) + 1 36 | 37 | p1' * p1 + p2' * p2 <= Pt 38 | cvx_end 39 | 40 | betaa = [beta1, beta2]; 41 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/multicast/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/multicast/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/multicast/multicast_wmmse.m: -------------------------------------------------------------------------------- 1 | function [pc, c, MMFrate] = multicast_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt; 6 | 7 | [U, ~, ~] = svd(H); 8 | pc = U(:, 1) * sqrt(P_c); 9 | 10 | MMFrate_last = -inf; 11 | maxIter = 1000; 12 | 13 | for n = 1:maxIter 14 | 15 | T_c1 = square_abs(H(:, 1)'*pc) + 1; 16 | T_c2 = square_abs(H(:, 2)'*pc) + 1; 17 | 18 | g_ck = zeros(K, 1); 19 | g_ck(1) = pc' * H(:, 1) / T_c1; 20 | g_ck(2) = pc' * H(:, 2) / T_c2; 21 | 22 | u_ck = zeros(K, 1); 23 | u_ck(1) = T_c1 / log(2); 24 | u_ck(2) = T_c2 / log(2); 25 | 26 | [pc, c, MMFrate] = multicast_wmmse_update(H, Pt, g_ck, u_ck); 27 | 28 | fprintf("Multicast | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 29 | 30 | if abs(MMFrate - MMFrate_last) <= tolerance 31 | break; 32 | end 33 | MMFrate_last = MMFrate; 34 | 35 | end 36 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/multicast/multicast_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/multicast/multicast_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/multicast/multicast_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | multicast_wmmse_time_list = []; 9 | multicast_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | multicast_mmf_rate = 0; 17 | 18 | tic; 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = multicast_wmmse(H, Pt, tolerance); 23 | multicast_mmf_rate = multicast_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | multicast_wmmse_time_list = [multicast_wmmse_time_list, time / channel_num]; 29 | multicast_wmmse_mmf_rate_list = [multicast_wmmse_mmf_rate_list, multicast_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'multicast_wmmse.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'multicast_wmmse_time_list', ... 41 | 'multicast_wmmse_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/multicast/multicast_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [pc, c, MMFrate] = multicast_wmmse_update(H, Pt, g_ck, u_ck) 2 | 3 | [Nt, ~] = size(H); 4 | cvx_begin quiet 5 | variable t 6 | variable x(2) 7 | variable pc(Nt) complex 8 | 9 | T_c1 = square_abs(H(:, 1)'*pc) + 1; 10 | T_c2 = square_abs(H(:, 2)'*pc) + 1; 11 | 12 | epsilon_c1 = square_abs(g_ck(1))*T_c1 - 2*real(g_ck(1)*H(:, 1)'*pc) + 1; 13 | epsilon_c2 = square_abs(g_ck(2))*T_c2 - 2*real(g_ck(2)*H(:, 2)'*pc) + 1; 14 | 15 | xi_c1 = u_ck(1)*epsilon_c1 - log2(u_ck(1)); 16 | xi_c2 = u_ck(2)*epsilon_c2 - log2(u_ck(2)); 17 | 18 | minimise(t) 19 | subject to 20 | t >= x(1) 21 | t >= x(2) 22 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c1 23 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c2 24 | pc'*pc <= Pt 25 | x <= 0 26 | 27 | cvx_end 28 | 29 | MMFrate = - t; 30 | c = -x; 31 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/noma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/noma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/noma/noma_wmmse.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = noma_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_p = Pt / K; 6 | 7 | P = H ./ vecnorm(H) * sqrt(P_p); 8 | p1 = P(:, 1); 9 | p2 = P(:, 2); 10 | 11 | MMFrate_last = -inf; 12 | maxIter = 1000; 13 | 14 | for n = 1:maxIter 15 | 16 | T_11 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 17 | T_21 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 18 | T_22 = square_abs(H(:, 2)'*p2) + 1; 19 | 20 | g_11 = p1' * H(:, 1) / T_11; 21 | g_21 = p1' * H(:, 2) / T_21; 22 | g_22 = p2' * H(:, 2) / T_22; 23 | 24 | u_11 = T_11 / (T_11 - square_abs(H(:, 1)'*p1)) / log(2); 25 | u_21 = T_21 / T_22 / log(2); 26 | u_22 = T_22 / log(2); 27 | 28 | [p1, p2, MMFrate] = noma_wmmse_update(H, Pt, g_11, g_21, g_22, u_11, u_21, u_22); 29 | 30 | fprintf("NOMA | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 31 | 32 | if abs(MMFrate - MMFrate_last) <= tolerance 33 | break; 34 | end 35 | MMFrate_last = MMFrate; 36 | 37 | end 38 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/noma/noma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/noma/noma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/noma/noma_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | noma_wmmse_time_list = []; 9 | noma_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | noma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate1] = noma_wmmse(H, Pt, tolerance); 23 | [~, ~, mmf_rate2] = noma_wmmse(H(:, [2, 1]), Pt, tolerance); 24 | noma_mmf_rate = noma_mmf_rate + max(mmf_rate1, mmf_rate2); 25 | 26 | end 27 | time = toc; 28 | 29 | noma_wmmse_time_list = [noma_wmmse_time_list, time / channel_num]; 30 | noma_wmmse_mmf_rate_list = [noma_wmmse_mmf_rate_list, noma_mmf_rate / channel_num]; 31 | 32 | end 33 | 34 | filename = 'noma_wmmse.mat'; 35 | save(filename, ... 36 | 'K', ... 37 | 'Nt', ... 38 | 'channel_num', ... 39 | 'Sigma', ... 40 | 'snrdB_list', ... 41 | 'noma_wmmse_time_list', ... 42 | 'noma_wmmse_mmf_rate_list'); 43 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/noma/noma_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = noma_wmmse_update(H, Pt, g_11, g_21, g_22, u_11, u_21, u_22) 2 | 3 | [Nt, K] = size(H); 4 | 5 | cvx_begin quiet 6 | 7 | variable t 8 | variable p1(Nt) complex 9 | variable p2(Nt) complex 10 | 11 | T_11 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 12 | T_21 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 13 | T_22 = square_abs(H(:, 2)'*p2) + 1; 14 | 15 | epsilon_11 = square_abs(g_11)*T_11 - 2*real(g_11*H(:, 1)'*p1) + 1; 16 | epsilon_21 = square_abs(g_21)*T_21 - 2*real(g_21*H(:, 2)'*p1) + 1; 17 | epsilon_22 = square_abs(g_22)*T_22 - 2*real(g_22*H(:, 2)'*p2) + 1; 18 | 19 | xi_11 = u_11*epsilon_11 - log2(u_11); 20 | xi_21 = u_21*epsilon_21 - log2(u_21); 21 | xi_22 = u_22*epsilon_22 - log2(u_22); 22 | 23 | minimise(t) 24 | subject to 25 | t >= xi_11 26 | t >= xi_21 27 | t >= xi_22 28 | p1'*p1 + p2'*p2 <= Pt 29 | 30 | cvx_end 31 | 32 | MMFrate = 1/log(2) + log2(log(2)) - t; 33 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/rsma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/rsma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/rsma/rsma_wmmse.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, pc, c, MMFrate] = rsma_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_c = Pt * 0.5; 6 | P_p = (Pt-P_c) / K; 7 | 8 | [U, ~, ~] = svd(H); 9 | pc = U(:, 1) * sqrt(P_c); 10 | P = H ./ vecnorm(H) * sqrt(P_p); 11 | p1 = P(:, 1); 12 | p2 = P(:, 2); 13 | 14 | MMFrate_last = -inf; 15 | maxIter = 1000; 16 | 17 | for n = 1:maxIter 18 | 19 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 20 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 21 | 22 | g_k = zeros(K, 1); 23 | g_k(1) = p1' * H(:, 1) / T_1; 24 | g_k(2) = p2' * H(:, 2) / T_2; 25 | 26 | u_k = zeros(K, 1); 27 | u_k(1) = T_1 / (T_1 - square_abs(H(:, 1)'*p1)) / log(2); 28 | u_k(2) = T_2 / (T_2 - square_abs(H(:, 2)'*p2)) / log(2); 29 | 30 | T_c1 = square_abs(H(:, 1)'*pc) + square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 31 | T_c2 = square_abs(H(:, 2)'*pc) + square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 32 | 33 | g_ck = zeros(K, 1); 34 | g_ck(1) = pc' * H(:, 1) / T_c1; 35 | g_ck(2) = pc' * H(:, 2) / T_c2; 36 | 37 | u_ck = zeros(K, 1); 38 | u_ck(1) = T_c1 / T_1 / log(2); 39 | u_ck(2) = T_c2 / T_2 / log(2); 40 | 41 | [p1, p2, pc, c, MMFrate] = rsma_wmmse_update(H, Pt, g_ck, g_k, u_ck, u_k); 42 | 43 | fprintf("RSMA | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 44 | 45 | if abs(MMFrate - MMFrate_last) <= tolerance 46 | break; 47 | end 48 | MMFrate_last = MMFrate; 49 | 50 | end 51 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/rsma/rsma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/rsma/rsma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/rsma/rsma_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | rsma_wmmse_time_list = []; 9 | rsma_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | rsma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, ~, ~, mmf_rate] = rsma_wmmse(H, Pt, tolerance); 23 | rsma_mmf_rate = rsma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | rsma_wmmse_time_list = [rsma_wmmse_time_list, time / channel_num]; 29 | rsma_wmmse_mmf_rate_list = [rsma_wmmse_mmf_rate_list, rsma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'rsma_wmmse.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'rsma_wmmse_time_list', ... 41 | 'rsma_wmmse_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/rsma/rsma_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, pc, c, MMFrate] = rsma_wmmse_update(H, Pt, g_ck, g_k, u_ck, u_k) 2 | 3 | [Nt, ~] = size(H); 4 | cvx_begin quiet 5 | variable t 6 | variable x(2) 7 | variable p1(Nt) complex 8 | variable p2(Nt) complex 9 | variable pc(Nt) complex 10 | 11 | T_c1 = square_abs(H(:, 1)'*pc) + square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 12 | T_c2 = square_abs(H(:, 2)'*pc) + square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 13 | 14 | epsilon_c1 = square_abs(g_ck(1))*T_c1 - 2*real(g_ck(1)*H(:, 1)'*pc) + 1; 15 | epsilon_c2 = square_abs(g_ck(2))*T_c2 - 2*real(g_ck(2)*H(:, 2)'*pc) + 1; 16 | 17 | xi_c1 = u_ck(1)*epsilon_c1 - log2(u_ck(1)); 18 | xi_c2 = u_ck(2)*epsilon_c2 - log2(u_ck(2)); 19 | 20 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 21 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 22 | 23 | epsilon_1 = square_abs(g_k(1))*T_1 - 2*real(g_k(1)*H(:, 1)'*p1) + 1; 24 | epsilon_2 = square_abs(g_k(2))*T_2 - 2*real(g_k(2)*H(:, 2)'*p2) + 1; 25 | 26 | xi_1 = u_k(1)*epsilon_1 - log2(u_k(1)); 27 | xi_2 = u_k(2)*epsilon_2 - log2(u_k(2)); 28 | 29 | minimise(t) 30 | subject to 31 | t >= xi_1 + x(1) 32 | t >= xi_2 + x(2) 33 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c1 34 | 1/log(2) + log2(log(2)) + x(1) + x(2) >= xi_c2 35 | p1'*p1 + p2'*p2 + pc'*pc <= Pt 36 | x <= 0 37 | 38 | cvx_end 39 | 40 | MMFrate = 1/log(2) + log2(log(2)) - t; 41 | c = -x; -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/sdma/channel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/sdma/channel.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/sdma/sdma_wmmse.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = sdma_wmmse(H, Pt, tolerance) 2 | 3 | [Nt, K] = size(H); 4 | 5 | P_p = Pt / K; 6 | 7 | P = H ./ vecnorm(H) * sqrt(P_p); 8 | p1 = P(:, 1); 9 | p2 = P(:, 2); 10 | 11 | MMFrate_last = -inf; 12 | maxIter = 1000; 13 | 14 | for n = 1:maxIter 15 | 16 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 17 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 18 | 19 | g_k = zeros(K, 1); 20 | g_k(1) = p1' * H(:, 1) / T_1; 21 | g_k(2) = p2' * H(:, 2) / T_2; 22 | 23 | u_k = zeros(K, 1); 24 | u_k(1) = T_1 / (T_1 - square_abs(H(:, 1)'*p1)) / log(2); 25 | u_k(2) = T_2 / (T_2 - square_abs(H(:, 2)'*p2)) / log(2); 26 | 27 | [p1, p2, MMFrate] = sdma_wmmse_update(H, Pt, g_k, u_k); 28 | 29 | fprintf("SDMA | %3d | obj = %f | |obj - obj_last| = %f\n", n, MMFrate, abs(MMFrate - MMFrate_last)); 30 | 31 | if abs(MMFrate - MMFrate_last) <= tolerance 32 | break; 33 | end 34 | MMFrate_last = MMFrate; 35 | 36 | end 37 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/sdma/sdma_wmmse.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YijieLinaMao/RSMA-low-complexity-MaxMin/76037277d2c76ae3b871402c34dbedd62e6279b2/Figure1/one_and_zero_point_three/wmmse/sdma/sdma_wmmse.mat -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/sdma/sdma_wmmse_main.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | clc; 3 | 4 | load channel.mat; 5 | 6 | snrdB_list = 5:5:30; 7 | 8 | sdma_wmmse_time_list = []; 9 | sdma_wmmse_mmf_rate_list = []; 10 | 11 | tolerance = 1e-3; 12 | 13 | for snrdB = snrdB_list 14 | 15 | Pt = 10 ^ (snrdB/10); 16 | sdma_mmf_rate = 0; 17 | 18 | tic 19 | for n = 1:channel_num 20 | 21 | H = channel(:, :, n); 22 | [~, ~, mmf_rate] = sdma_wmmse(H, Pt, tolerance); 23 | sdma_mmf_rate = sdma_mmf_rate + mmf_rate; 24 | 25 | end 26 | time = toc; 27 | 28 | sdma_wmmse_time_list = [sdma_wmmse_time_list, time / channel_num]; 29 | sdma_wmmse_mmf_rate_list = [sdma_wmmse_mmf_rate_list, sdma_mmf_rate / channel_num]; 30 | 31 | end 32 | 33 | filename = 'sdma_wmmse.mat'; 34 | save(filename, ... 35 | 'K', ... 36 | 'Nt', ... 37 | 'channel_num', ... 38 | 'Sigma', ... 39 | 'snrdB_list', ... 40 | 'sdma_wmmse_time_list', ... 41 | 'sdma_wmmse_mmf_rate_list'); 42 | -------------------------------------------------------------------------------- /Figure1/one_and_zero_point_three/wmmse/sdma/sdma_wmmse_update.m: -------------------------------------------------------------------------------- 1 | function [p1, p2, MMFrate] = sdma_wmmse_update(H, Pt, g_k, u_k) 2 | 3 | [Nt, ~] = size(H); 4 | cvx_begin quiet 5 | variable t 6 | variable p1(Nt) complex 7 | variable p2(Nt) complex 8 | 9 | T_1 = square_abs(H(:, 1)'*p1) + square_abs(H(:, 1)'*p2) + 1; 10 | T_2 = square_abs(H(:, 2)'*p1) + square_abs(H(:, 2)'*p2) + 1; 11 | 12 | epsilon_1 = square_abs(g_k(1))*T_1 - 2*real(g_k(1)*H(:, 1)'*p1) + 1; 13 | epsilon_2 = square_abs(g_k(2))*T_2 - 2*real(g_k(2)*H(:, 2)'*p2) + 1; 14 | 15 | xi_1 = u_k(1)*epsilon_1 - log2(u_k(1)); 16 | xi_2 = u_k(2)*epsilon_2 - log2(u_k(2)); 17 | 18 | minimise(t) 19 | subject to 20 | t >= xi_1 21 | t >= xi_2 22 | p1'*p1 + p2'*p2 <= Pt 23 | 24 | cvx_end 25 | 26 | MMFrate = 1/log(2) + log2(log(2)) - t; 27 | -------------------------------------------------------------------------------- /Figure2/lowComplexity.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate and power allocatoin 2 | % H is channel matrix 3 | % P is power constraint 4 | 5 | function [t, rate] = lowComplexity(H, P) 6 | 7 | if H(:, 1)'*H(:, 1) < H(:, 2)'*H(:, 2) 8 | H = H(:, [2, 1]); 9 | end 10 | 11 | H_bar = zeros(size(H)); 12 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 13 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 14 | 15 | rho = 1 - abs(H_bar(:, 1)' * H_bar(:, 2)) ^ 2; 16 | 17 | coefficient = 1 / sqrt(2*(1 + abs(H_bar(:, 1)'*H_bar(:, 2)))); 18 | pc_bar = coefficient * (H_bar(:, 1) + H_bar(:, 2)*exp(-1i*angle(H_bar(:, 1)'*H_bar(:, 2)))); 19 | 20 | rho1 = H(:, 1)' * H(:, 1) * rho; 21 | rho2 = H(:, 2)' * H(:, 2) * rho; 22 | 23 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 24 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 25 | 26 | Gamma = max(1/rho2 - 1/rho1, 0); 27 | 28 | tList = [0, 1]; 29 | 30 | t = Gamma / P; 31 | if t < 1 && t > 0 32 | % t + 0.001 and t - 0.001 are for jump discontinuity 33 | tList = [tList, t, t + 0.001, t - 0.001]; 34 | end 35 | 36 | t = (0.5*rho2*Gamma - rhoc2*P - 1)/(rho2*P - 2*rhoc2*P) - 1/rho1/P - Gamma/P/2; 37 | if t < 1 && t > 0 38 | tList = [tList, t]; 39 | end 40 | 41 | t = rhoc2 / (rho1+rhoc2); 42 | if t < 1 && t > 0 43 | tList = [tList, t]; 44 | end 45 | 46 | t = (2*rhoc2*P - rho1*Gamma - rho2*Gamma) / (rho1 - rho2 + 2*rhoc2) / P; 47 | if t < 1 && t > 0 48 | tList = [tList, t]; 49 | end 50 | 51 | rateList = []; 52 | for t = tList 53 | rate = maxMinRate(H, t, P); 54 | rateList = [rateList, rate]; 55 | end 56 | 57 | [rate, optimalIndex] = max(rateList); 58 | t = tList(optimalIndex); 59 | -------------------------------------------------------------------------------- /Figure2/maxMinRate.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate 2 | % H is channel matrix 3 | % tP is the power of private streams and (1 − t)P is the power of common stream 4 | % P is power constraint 5 | 6 | function rate = maxMinRate(H, t, P) 7 | 8 | % normalized channel vectors 9 | H_bar = zeros(size(H)); 10 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 11 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 12 | 13 | rho = 1 - abs(H_bar(:, 1)'*H_bar(:, 2))^2; 14 | 15 | pc_bar = 1 / sqrt(2 * (1 + abs(H_bar(:, 1)' * H_bar(:, 2)))) * ... 16 | (H_bar(:, 1) + H_bar(:, 2) * exp(-1i * angle(H_bar(:, 1)' * H_bar(:, 2)))); 17 | 18 | rho1 = H(:, 1)' * H(:, 1) * rho; 19 | rho2 = H(:, 2)' * H(:, 2) * rho; 20 | 21 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 22 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 23 | 24 | % Gamma is non-negative mathematically, the max is to correct the computational error 25 | Gamma = max(1/rho2 - 1/rho1, 0); 26 | 27 | if t*P > Gamma 28 | % RSMA, SDMA 29 | P1 = 0.5 * (t*P + Gamma); 30 | P2 = 0.5 * (t*P - Gamma); 31 | Pc = (1-t) * P; 32 | R1 = log2(1 + rho1*P1); 33 | R2 = log2(1 + rho2*P2); 34 | Rc = log2(1 + rhoc1*Pc/(1 + rho1*P1)); 35 | rate = R1 + R2 + Rc - max(R1 - R2 - Rc, 0); 36 | rate = 0.5 * rate; 37 | else 38 | P1 = t * P; 39 | Pc = (1-t) * P; 40 | if t > 1e-6 41 | % NOMA 42 | rate = log2(1 + min([rho1 * P1, rhoc2 * Pc])); 43 | else 44 | % Multicast 45 | Rc = log2(1 + rhoc2*Pc); 46 | rate = 0.5 * Rc; 47 | end 48 | end -------------------------------------------------------------------------------- /Figure2/optimalT.m: -------------------------------------------------------------------------------- 1 | % This is a code package related to the following paper: 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % F. Luo and Y. Mao, "A Practical Max-Min Fair Resource Allocation Algorithm 4 | % for Rate-Splitting Multiple Access," in IEEE Communications Letters, 5 | % vol. 27, no. 12, pp. 3285-3289, Dec. 2023, doi: 10.1109/LCOMM.2023.3329149. 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | % 8 | % The code is implemented in MATLAB environment with CVX toolbox 9 | % assisted. 10 | % 11 | % Fig. 2 of the above paper will be reproduced by running this MATLAB 12 | % script. By changing the variable 'SNRdB', you can reproduce Fig. 2(a-c). 13 | % 14 | % This script relies on function 'lowComplexity.m' and 'maxMinRate.m'. 15 | % Don't forget to put 'lowComplexity.m' and 'maxMinRate.m' in the same folder. 16 | 17 | 18 | clear all; 19 | clc; 20 | 21 | % signal to noise ratio in decibel 22 | SNRdB = 10; 23 | Pt = 10 ^ (SNRdB/10); 24 | 25 | % these two parameters control the density of grid 26 | gammaNumber = 400; 27 | thetaNumber = 300; 28 | 29 | gammaList = linspace(0.1, 1, gammaNumber); 30 | thetaList = linspace(0.01, pi - 0.01, thetaNumber); 31 | 32 | optimalTList = zeros(gammaNumber, thetaNumber); 33 | 34 | for gammaIndex = 1:gammaNumber 35 | for thetaIndex = 1:thetaNumber 36 | 37 | % channel matrix 38 | H = [1 / sqrt(2), gammaList(gammaIndex) / sqrt(2) 39 | 1 / sqrt(2), gammaList(gammaIndex) / sqrt(2) * exp(-1i*thetaList(thetaIndex))]; 40 | 41 | % calculate the max-min rate 42 | [t, ~] = lowComplexity(H, Pt); 43 | 44 | optimalTList(gammaIndex, thetaIndex) = t; 45 | 46 | end 47 | end 48 | gammadB = 20 * log10(gammaList); 49 | rhoList = 0.5 * (1 - cos(thetaList)); 50 | [Rho, Gamma] = meshgrid(rhoList, gammadB); 51 | 52 | figure; 53 | contourf(Rho, Gamma, optimalTList, 30, 'ShowText', 'off', 'LineWidth', 0.01); 54 | xlabel('\rho', 'FontSize', 20); 55 | ylabel('channel strength disparity \gamma_{dB}[dB]', 'FontSize', 14); 56 | title(sprintf('(c) SNR = %ddB', SNRdB), 'FontSize', 14, 'FontName', 'Times New Roman', 'FontWeight', 'Normal'); 57 | colormap default; 58 | c = colorbar; 59 | c.FontSize = 14; 60 | hold on; 61 | set(gca, 'LooseInset', [0,0,0.02,0]); 62 | set(gca, 'FontSize', 14); 63 | -------------------------------------------------------------------------------- /Figure3/lowComplexity.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate and power allocatoin 2 | % H is channel matrix 3 | % P is power constraint 4 | 5 | function [t, rate] = lowComplexity(H, P) 6 | 7 | if H(:, 1)'*H(:, 1) < H(:, 2)'*H(:, 2) 8 | H = H(:, [2, 1]); 9 | end 10 | 11 | H_bar = zeros(size(H)); 12 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 13 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 14 | 15 | rho = 1 - abs(H_bar(:, 1)' * H_bar(:, 2)) ^ 2; 16 | 17 | coefficient = 1 / sqrt(2*(1 + abs(H_bar(:, 1)'*H_bar(:, 2)))); 18 | pc_bar = coefficient * (H_bar(:, 1) + H_bar(:, 2)*exp(-1i*angle(H_bar(:, 1)'*H_bar(:, 2)))); 19 | 20 | rho1 = H(:, 1)' * H(:, 1) * rho; 21 | rho2 = H(:, 2)' * H(:, 2) * rho; 22 | 23 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 24 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 25 | 26 | Gamma = max(1/rho2 - 1/rho1, 0); 27 | 28 | tList = [0, 1]; 29 | 30 | t = Gamma / P; 31 | if t < 1 && t > 0 32 | % t + 0.001 and t - 0.001 are for jump discontinuity 33 | tList = [tList, t, t + 0.001, t - 0.001]; 34 | end 35 | 36 | t = (0.5*rho2*Gamma - rhoc2*P - 1)/(rho2*P - 2*rhoc2*P) - 1/rho1/P - Gamma/P/2; 37 | if t < 1 && t > 0 38 | tList = [tList, t]; 39 | end 40 | 41 | t = rhoc2 / (rho1+rhoc2); 42 | if t < 1 && t > 0 43 | tList = [tList, t]; 44 | end 45 | 46 | t = (2*rhoc2*P - rho1*Gamma - rho2*Gamma) / (rho1 - rho2 + 2*rhoc2) / P; 47 | if t < 1 && t > 0 48 | tList = [tList, t]; 49 | end 50 | 51 | rateList = []; 52 | for t = tList 53 | rate = maxMinRate(H, t, P); 54 | rateList = [rateList, rate]; 55 | end 56 | 57 | [rate, optimalIndex] = max(rateList); 58 | t = tList(optimalIndex); 59 | -------------------------------------------------------------------------------- /Figure3/maxMinRate.m: -------------------------------------------------------------------------------- 1 | % This function calculate the max-min rate 2 | % H is channel matrix 3 | % tP is the power of private streams and (1 − t)P is the power of common stream 4 | % P is power constraint 5 | 6 | function rate = maxMinRate(H, t, P) 7 | 8 | % normalized channel vectors 9 | H_bar = zeros(size(H)); 10 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 11 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 12 | 13 | rho = 1 - abs(H_bar(:, 1)'*H_bar(:, 2))^2; 14 | 15 | pc_bar = 1 / sqrt(2 * (1 + abs(H_bar(:, 1)' * H_bar(:, 2)))) * ... 16 | (H_bar(:, 1) + H_bar(:, 2) * exp(-1i * angle(H_bar(:, 1)' * H_bar(:, 2)))); 17 | 18 | rho1 = H(:, 1)' * H(:, 1) * rho; 19 | rho2 = H(:, 2)' * H(:, 2) * rho; 20 | 21 | rhoc1 = abs(H(:, 1)'*pc_bar) ^ 2; 22 | rhoc2 = abs(H(:, 2)'*pc_bar) ^ 2; 23 | 24 | % Gamma is non-negative mathematically, the max is to correct the computational error 25 | Gamma = max(1/rho2 - 1/rho1, 0); 26 | 27 | if t*P > Gamma 28 | % RSMA, SDMA 29 | P1 = 0.5 * (t*P + Gamma); 30 | P2 = 0.5 * (t*P - Gamma); 31 | Pc = (1-t) * P; 32 | R1 = log2(1 + rho1*P1); 33 | R2 = log2(1 + rho2*P2); 34 | Rc = log2(1 + rhoc1*Pc/(1 + rho1*P1)); 35 | rate = R1 + R2 + Rc - max(R1 - R2 - Rc, 0); 36 | rate = 0.5 * rate; 37 | else 38 | P1 = t * P; 39 | Pc = (1-t) * P; 40 | if t > 1e-6 41 | % NOMA 42 | rate = log2(1 + min([rho1 * P1, rhoc2 * Pc])); 43 | else 44 | % Multicast 45 | Rc = log2(1 + rhoc2*Pc); 46 | rate = 0.5 * Rc; 47 | end 48 | end -------------------------------------------------------------------------------- /Figure3/relativeGain.m: -------------------------------------------------------------------------------- 1 | % This is a code package related to the following paper: 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % F. Luo and Y. Mao, "A Practical Max-Min Fair Resource Allocation Algorithm 4 | % for Rate-Splitting Multiple Access," in IEEE Communications Letters, 5 | % vol. 27, no. 12, pp. 3285-3289, Dec. 2023, doi: 10.1109/LCOMM.2023.3329149. 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | % 8 | % The code is implemented in MATLAB environment with CVX toolbox 9 | % assisted. 10 | % 11 | % This script relies on function 'maxMinRate.m'. 12 | % Don't forget to put 'maxMinRate.m' in the same folder. 13 | 14 | 15 | clear all; 16 | clc; 17 | 18 | % signal to noise ratio in decibel 19 | SNRdB = 30; 20 | Pt = 10 ^ (SNRdB/10); 21 | 22 | % these two parameters control the density of grid 23 | gammaNumber = 400; 24 | thetaNumber = 300; 25 | 26 | gammaList = linspace(0.1, 1, gammaNumber); 27 | thetaList = linspace(0.01, pi - 0.01, thetaNumber); 28 | 29 | relativeGainList = zeros(gammaNumber, thetaNumber); 30 | relativeGainOverSDMA = zeros(gammaNumber, thetaNumber); 31 | relativeGainOverNOMA = zeros(gammaNumber, thetaNumber); 32 | relativeGainOverMulticast = zeros(gammaNumber, thetaNumber); 33 | 34 | for gammaIndex = 1:gammaNumber 35 | for thetaIndex = 1:thetaNumber 36 | 37 | % channel matrix 38 | H = [1 / sqrt(2), gammaList(gammaIndex) / sqrt(2) 39 | 1 / sqrt(2), gammaList(gammaIndex) / sqrt(2) * exp(-1i*thetaList(thetaIndex))]; 40 | 41 | % normalized channel vectors 42 | H_bar = zeros(size(H)); 43 | H_bar(:, 1) = H(:, 1) / norm(H(:, 1)); 44 | H_bar(:, 2) = H(:, 2) / norm(H(:, 2)); 45 | 46 | rho = 1 - abs(H_bar(:, 1)' * H_bar(:, 2)) ^ 2; 47 | 48 | % common beamforming vector's direction 49 | pc_bar = 1 / sqrt(2 * (1 + abs(H_bar(:, 1)' * H_bar(:, 2)))) * ... 50 | (H_bar(:, 1) + H_bar(:, 2) * ... 51 | exp(-1i * angle(H_bar(:, 1)' * H_bar(:, 2)))); 52 | 53 | rho1 = H(:, 1)' * H(:, 1) * rho; 54 | rho2 = H(:, 2)' * H(:, 2) * rho; 55 | 56 | rhoc1 = abs(H(:, 1)' * pc_bar) ^ 2; 57 | rhoc2 = abs(H(:, 2)' * pc_bar) ^ 2; 58 | 59 | % Gamma is non-negative mathematically, the max is to correct the 60 | % computational error 61 | Gamma = max(1 / rho2 - 1 / rho1, 0); 62 | 63 | if Pt > Gamma 64 | sdmaRate = maxMinRate(H, 1, Pt); 65 | end 66 | multicastRate = maxMinRate(H, 0, Pt); 67 | 68 | rsmaList = []; 69 | nomaList = []; 70 | 71 | % Gamma/Pt is a non-continuous point 72 | t = Gamma/Pt - 0.001; 73 | if t < 1 && t > 0 74 | nomaList = [nomaList, t]; 75 | end 76 | 77 | % Gamma/Pt is a non-continuous point 78 | t = Gamma/Pt + 0.001; 79 | if t < 1 && t > 0 80 | rsmaList = [rsmaList, t]; 81 | end 82 | 83 | t = rhoc2 / (rho1+rhoc2); 84 | if t < 1 && t > 0 && t*Pt < Gamma 85 | nomaList = [nomaList, t]; 86 | end 87 | 88 | t = (0.5 * rho2 * Gamma - rhoc2 * Pt - 1) / ... 89 | (rho2 * Pt - 2 * rhoc2 * Pt) - 1 / rho1 / Pt - Gamma / Pt / 2; 90 | if t < 1 && t > 0 && t*Pt > Gamma 91 | rsmaList = [rsmaList, t]; 92 | end 93 | 94 | % zero is non-continuous point 95 | t = 0.001; 96 | if t*Pt < Gamma 97 | nomaList = [nomaList, t]; 98 | end 99 | 100 | t = (2 * rhoc2 * Pt - rho1 * Gamma - rho2 * Gamma) / ... 101 | (rho1 - rho2 + 2 * rhoc2) / Pt; 102 | if t < 1 && t > 0 && t*Pt > Gamma 103 | rsmaList = [rsmaList, t]; 104 | end 105 | 106 | nomaRateList = []; 107 | for t = nomaList 108 | nomaRate = maxMinRate(H, t, Pt); 109 | nomaRateList = [nomaRateList, nomaRate]; 110 | end 111 | nomaRate = max(nomaRateList); 112 | 113 | rsmaRateList = []; 114 | for t = rsmaList 115 | rsmaRate = maxMinRate(H, t, Pt); 116 | rsmaRateList = [rsmaRateList, rsmaRate]; 117 | end 118 | rsmaRate = max(rsmaRateList); 119 | 120 | if Gamma - Pt >= -0.001 * Pt 121 | relativeGainOverSDMA(gammaIndex, thetaIndex) = 0; 122 | relativeGainOverNOMA(gammaIndex, thetaIndex) = 0; 123 | relativeGainOverMulticast(gammaIndex, thetaIndex) = 0; 124 | relativeGainList(gammaIndex, thetaIndex) = 0; 125 | else 126 | if Gamma <= 0.001 * Pt 127 | relativeGainOverNOMA(gammaIndex, thetaIndex) = 0; 128 | else 129 | relativeGainOverNOMA(gammaIndex, thetaIndex) = max((rsmaRate-nomaRate)/nomaRate, 0); 130 | end 131 | relativeGainOverSDMA(gammaIndex, thetaIndex) = max((rsmaRate-sdmaRate)/sdmaRate, 0); 132 | relativeGainOverMulticast(gammaIndex, thetaIndex) = max((rsmaRate-multicastRate)/multicastRate, 0); 133 | num = rsmaRate - max([nomaRate, sdmaRate, multicastRate]); 134 | den = max([nomaRate, sdmaRate, multicastRate]); 135 | relativeGainList(gammaIndex, thetaIndex) = max(num/den, 0); 136 | end 137 | end 138 | end 139 | gammadB = 20 * log10(gammaList); 140 | rhoList = 0.5 * (1 - cos(thetaList)); 141 | [Rho, Gamma] = meshgrid(rhoList, gammadB); 142 | 143 | figure; 144 | contourf(Rho, Gamma, relativeGainList, 20, 'ShowText', 'off', 'LineWidth', 0.01); 145 | xlabel('\rho', 'FontSize', 20); 146 | ylabel('channel strength disparity \gamma_{dB}[dB]', 'FontSize', 14); 147 | title(sprintf('SNR = %ddB', SNRdB), 'FontSize', 14); 148 | colormap default; 149 | c = colorbar; 150 | c.FontSize = 14; 151 | 152 | % change the colorbar label to percentages 153 | tickLabels = []; 154 | for item = c.Ticks 155 | tickLabels = [tickLabels, strcat(string(100*item), '%')]; 156 | end 157 | c.TickLabels = tickLabels; 158 | 159 | % the percentage points in the figure 160 | hold on; 161 | x = rhoList([90, 150, 210]); 162 | y = gammadB([35, 120, 200, 300]); 163 | [X, Y] = meshgrid(x, y); 164 | plot(X, Y, 'Marker', 'x', 'LineStyle', 'none', 'MarkerEdgeColor', 'white', 'MarkerFaceColor', 'white'); 165 | 166 | % the percentages in the figure 167 | for m = [35, 120, 200, 300] 168 | for n = [90, 150, 210] 169 | txt = sprintf('(%.0f%%, %.0f%%, %.0f%%)', 100*relativeGainOverSDMA(m, n), 100*relativeGainOverNOMA(m, n), 100*relativeGainOverMulticast(m, n)); 170 | text(rhoList(n)-0.1, gammadB(m)+1, txt, 'Color', 'white'); 171 | end 172 | end 173 | set(gca, 'LooseInset', [0,0,0.035,0]); 174 | set(gca, 'FontSize', 14); 175 | 176 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A practical max-min fair resource allocation algorithm for rate-splitting multiple access 2 | 3 | This is a code package related to the following [paper](https://ieeexplore.ieee.org/document/10304220): 4 | 5 | F. Luo and Y. Mao, "A Practical Max-Min Fair Resource Allocation Algorithm for Rate-Splitting Multiple Access," in _IEEE Communications Letters_, vol. 27, no. 12, pp. 3285-3289, Dec. 2023, doi: 10.1109/LCOMM.2023.3329149. 6 | 7 | # Content of Code Package 8 | 9 | Here is a detailed description of the package: 10 | - The code in all packages are implemented in MATLAB environment with CVX toolbox assisted. 11 | - The procedure for Fig. 1: 12 | - Run 'channel_generate.m' and you will get a 'channel.mat' file. 13 | - Copy the 'channel.mat' file to every subfolders corresponding to each method. 14 | - Run every '\*main.m' MATLAB script and you will get corresponding '\*.mat' files. 15 | - Copy the '\*.mat' files to corresponding subfolders that is in 'data_processing' folder. 16 | - Run 'data_processing.m' MATLAB script. 17 | - Fig. 2 of the above paper will be reproduced by running MATLAB script 'optimalT.m'. By changing the variable 'SNRdB', you can reproduce Fig. 2(a-c). 18 | - Fig. 3 of the above paper will be reproduced by running MATLAB script 'relativeGain.m'. 19 | 20 | # Abstract of the Article 21 | 22 | This letter introduces a novel resource allocation algorithm for achieving max-min fairness (MMF) in a rate-splitting multiple access (RSMA) empowered multi-antenna broadcast channel. Specifically, we derive the closed-form solution for the optimal allocation of the common rate among users and the power between the common and private streams for a given practical low-complexity beamforming direction design. Numerical results show that the proposed algorithm achieves 90% of the MMF rate on average obtained by the conventional iterative optimization algorithm while only takes an average of 0.1 millisecond computational time, which is three orders of magnitude lower than the conventional algorithm. It is therefore a practical resource allocation algorithm for RSMA. 23 | 24 | # License and Referencing 25 | This code package is licensed under the GPLv2 license. If you in any way use this code for research that results in publications, please cite our original article listed above. 26 | 27 | # Acknowledgements 28 | 29 | This work has been supported in part by the National Natural Science Foundation of China under Grant 62201347; and in part by Shanghai Sailing Program under Grant 22YF1428400. --------------------------------------------------------------------------------