12#include "NetSim_utility.h"
13#include "LTENR_Fading.h"
18#define M_PI 3.14159265358979323846
22#define MIN(a, b) ((a) < (b) ? (a) : (b))
25static double gaussian_random(
void) {
26 double U1 = NETSIM_RAND_01();
27 double U2 = NETSIM_RAND_01();
28 return sqrt(-2.0 * log(U1)) * cos(2.0 * M_PI * U2);
32static int cmp_desc(
const void* a,
const void* b) {
33 double da = *(
double*)a, db = *(
double*)b;
34 if (da < db)
return 1;
35 if (da > db)
return -1;
41 for (UINT i = 0; i < NR * NT; i++) {
42 H[i].real = gaussian_random() / sqrt(2.0);
43 H[i].imag = gaussian_random() / sqrt(2.0);
49 double mu = sqrt(K / (2.0 * (K + 1.0)));
50 double sigma = sqrt(1.0 / (2.0 * (K + 1.0)));
51 for (UINT i = 0; i < NR * NT; i++) {
52 H[i].real = mu + sigma * gaussian_random();
53 H[i].imag = mu + sigma * gaussian_random();
58void LTENR_Beamforming_GetValue(
64 UINT layers = MIN(NT, NR);
65 double* results = malloc(layers *
sizeof(*results));
66 if (!results) { *eigenvalues = NULL;
return; }
70 double* w = malloc(NR *
sizeof(*w));
72 free(results); free(H); free(G); free(w);
73 *eigenvalues = NULL;
return;
78 while (retry < MAX_RETRIES && info != 0) {
79 if (fastFadingModel == FADING_MODEL_RICIAN) {
80 generate_rician_H(H, NR, NT, K_factor);
82 else if (fastFadingModel == FADING_MODEL_RAYLEIGH) {
84 generate_rayleigh_H(H, NR, NT);
88 for (UINT i = 0; i < NR; i++) {
89 for (UINT j = 0; j < NR; j++) {
91 for (UINT k = 0; k < NT; k++) {
92 double ar = H[i * NT + k].real, ai = H[i * NT + k].imag;
93 double br = H[j * NT + k].real, bi = -H[j * NT + k].imag;
94 sum.real += ar * br - ai * bi;
95 sum.imag += ar * bi + ai * br;
101 info = LAPACKE_zheevd(LAPACK_ROW_MAJOR,
'N',
'U', NR, G, NR, w);
102 if (info != 0) retry++;
106 for (UINT i = 0; i < layers; i++) results[i] = 0.0;
109 qsort(w, NR,
sizeof(*w), cmp_desc);
110 for (UINT i = 0; i < layers; i++) results[i] = w[i];
113 for (
int i = 0; i < layers; i++) {
114 double v = results[i];
115 if (v < 1e-12) v = 1e-12;
116 results[i] = 10.0 * log10(v);
119 for (UINT i = 0; i < layers; i++) {
120 (*eigenvalues)[i] = results[i];
123 free(H); free(G); free(w);