60 "Fading_Generator::set_LOS_power(): Relative_power can not be negative");
68 it_warning(
"Fading_Generator::set_LOS_doppler(): This function has no effect on this kind of generator");
73 it_warning(
"Fading_Generator::set_time_offset(): This function has no effect on this kind of generator");
78 it_warning(
"Fading_Generator::set_norm_doppler(): This function has no effect on this kind of generator");
83 it_warning(
"Fading_Generator::set_filter_length(): This function has no effect on this kind of generator");
88 it_warning(
"Fading_Generator::set_doppler_spectrum(): This function has no effect on this kind of generator");
93 it_warning(
"Fading_Generator::set_no_frequencies(): This function has no effect on this kind of generator");
98 it_warning(
"Fading_Generator::set_rice_method(): This function has no effect on this kind of generator");
103 it_warning(
"Fading_Generator::get_LOS_doppler(): This function has no effect on this kind of generator");
109 it_warning(
"Fading_Generator::get_time_offset(): This function has no effect on this kind of generator");
115 it_warning(
"Fading_Generator::get_filter_length(): This function has no effect on this kind of generator");
121 it_warning(
"Fading_Generator::get_norm_doppler(): This function has no effect on this kind of generator");
127 it_warning(
"Fading_Generator::get_doppler_spectrum(): This function has no effect on this kind of generator");
133 it_warning(
"Fading_Generator::get_no_frequencies(): This function has no effect on this kind of generator");
139 it_warning(
"Fading_Generator::get_rice_method(): This function has no effect on this kind of generator");
145 it_warning(
"Fading_Generator::shift_time_offset(): This function has no effect on this kind of generator");
162 output.set_size(no_samples,
false);
164 for (
int i = 0; i < no_samples; ++i) {
180 std::complex<double> static_sample =
randn_c();
185 static_sample_re = static_sample.real();
186 static_sample_im = static_sample.imag();
195 output.set_size(no_samples,
false);
196 output = std::complex<double>(static_sample_re,static_sample_im);
212 it_assert((norm_doppler > 0) && (norm_doppler <= 1.0),
213 "Correlated_Fading_Generator: Normalized Doppler out of range");
220 it_assert((relative_doppler >= 0) && (relative_doppler <= 1.0),
221 "Correlated_Fading_Generator::set_LOS_doppler(): Relative Doppler out of range");
267 "Rice_Fading_Generator::set_no_frequencies(): Too low number of Doppler frequencies");
286 it_error(
"Rice_Fading_Generator::init(): Wrong Rice method for this fading generator");
297 output.set_size(no_samples,
false);
301 double tmp_re, tmp_im;
303 for (
int i = 0; i < no_samples; i++) {
306 output(i) = std::complex<double>(tmp_re, tmp_im);
311 for (
int i = 0; i < no_samples; i++) {
314 output(i) = std::complex<double>(tmp_re, tmp_im);
322 for (
int i = 0; i < no_samples; i++) {
348 f2 =
sin(
pi / (2 * (
Ni + 1)) * (n - 0.5));
372 sgm_0_2 = 0.15 / (
std::sqrt(10.0) + 0.15);
380 it_error(
"Rice_Fading_Generator::init_MEDS(): Wrong spectrum method for this fading generator");
399 "FIR_Fading_Generator::set_filter_length(): Filter length should be at least 50");
407 double norm_dopp =
n_dopp;
409 while (norm_dopp < 0.1) {
429 int no_upsamples =
ceil_i(static_cast<double>(no_samples -
left_overs.size())
435 left_overs = output.right(output.size() - no_samples);
436 output.set_size(no_samples,
true);
439 for (
int i = 0; i < no_samples; i++) {
450 vec x_pos(L), x_neg(L), x(2*L + 1), h(2*L + 1);
451 for (
int i = 1; i <= L; i++) {
455 double x0 = 1.468813 *
std::pow(norm_dopp, 0.25);
473 generate_Jakes(no_samples, output);
476 for (
int i = 0; i < no_samples; i++) {
487 double df = 1.0 / Nfft;
491 while (noisesamp <= 10) {
497 "IFFT_Fading_Generator::generate_Jakes(): Too low normalized doppler or too small blocks of data. Results in an inefficient algorithm with lots of zero-padding");
500 vec Fpos =
linspace(0, 0.5, Nfft / 2 + 1);
504 for (
int i = 0; i < F.size(); i++) {
505 if (std::fabs(F(i)) <
n_dopp)
507 else if (std::fabs(F(i)) ==
n_dopp)
516 for (
int i = 0; i < noisesamp; ++i) {
518 x(Nfft - 1 - i) = S(Nfft - 1 - i) *
randn_c();
523 output = x.mid(0, no_samples);
532 const vec &delay_prof)
534 set_channel_profile(avg_power_dB, delay_prof);
539 set_channel_profile(profile);
545 "Channel_Specification::set_channel_profile(): Minimum relative delay must be 0");
546 it_assert(avg_power_dB.size() == delay_prof.size(),
547 "Channel_Specification::set_channel_profile(): Power and delay vectors must be of equal length");
549 "Channel_Specification::set_channel_profile(): First tap must be at zero delay");
550 for (
int i = 1; i < delay_prof.size(); i++) {
551 it_assert(delay_prof(i) > delay_prof(i - 1),
552 "Channel_Specification::set_channel_profile(): Delays should be sorted and unique");
555 N_taps = delay_prof.size();
556 a_prof_dB = avg_power_dB;
560 tap_doppler_spectrum.set_size(N_taps,
false);
561 tap_doppler_spectrum = Jakes;
564 set_LOS(
zeros(N_taps));
571 case ITU_Vehicular_A:
572 set_channel_profile(vec(
"0 -1 -9 -10 -15 -20"),
573 vec(
"0 310 710 1090 1730 2510") * 1e-9);
576 case ITU_Vehicular_B:
577 set_channel_profile(vec(
"-2.5 0 -12.8 -10 -25.2 -16"),
578 vec(
"0 300 8900 12900 17100 20000") * 1e-9);
581 case ITU_Pedestrian_A:
582 set_channel_profile(vec(
"0 -9.7 -19.2 -22.8"),
583 vec(
"0 110 190 410") * 1e-9);
586 case ITU_Pedestrian_B:
587 set_channel_profile(vec(
"0 -0.9 -4.9 -8 -7.8 -23.9"),
588 vec(
"0 200 800 1200 2300 3700") * 1e-9);
593 set_channel_profile(vec(
"-5.7 -7.6 -10.1 -10.2 -10.2 -11.5 -13.4 -16.3 -16.9 -17.1 -17.4 -19 -19 -19.8 -21.5 -21.6 -22.1 -22.6 -23.5 -24.3"),
594 vec(
"0 217 512 514 517 674 882 1230 1287 1311 1349 1533 1535 1622 1818 1836 1884 1943 2048 2140") * 1e-9);
598 set_channel_profile(vec(
"-5.2 -6.4 -8.4 -9.3 -10 -13.1 -15.3 -18.5 -20.4 -22.4"),
599 vec(
"0 42 101 129 149 245 312 410 469 528") * 1e-9);
600 set_LOS(0,
sqr(0.91 / 0.41), 0.7);
604 set_channel_profile(vec(
"-3.6 -8.9 -10.2 -11.5 -11.8 -12.7 -13.0 -16.2 -17.3 -17.7 -17.6 -22.7 -24.1 -25.8 -25.8 -26.2 -29 -29.9 -30 -30.7"),
605 vec(
"0 356 441 528 546 609 625 842 916 941 15000 16172 16492 16876 16882 16978 17615 17827 17849 18016") * 1e-9);
610 set_channel_profile(vec(
"0 -2 -10 -20"),
611 vec(
"0 200 400 600") * 1e-9);
612 set_LOS(0,
sqr(0.91 / 0.41), 0.7);
616 set_channel_profile(vec(
"0 -4 -8 -12 -16 -20"),
617 vec(
"0 100 200 300 400 500") * 1e-9);
618 set_LOS(0,
sqr(0.91 / 0.41), 0.7);
622 set_channel_profile(vec(
"-3 0 -2 -6 -8 -10"),
623 vec(
"0 200 600 1600 2400 5000") * 1e-9);
631 set_channel_profile(vec(
"-3 0 -2 -6 -8 -10"),
632 vec(
"0 200 500 1600 2300 5000") * 1e-9);
639 set_channel_profile(vec(
"-4 -3 0 -2 -3 -5 -7 -5 -6 -9 -11 -10"),
640 vec(
"0 200 400 600 800 1200 1400 1800 2400 3000 3200 5000") * 1e-9);
652 case COST207_TU12alt:
653 set_channel_profile(vec(
"-4 -3 0 -2.6 -3 -5 -7 -5 -6.5 -8.6 -11 -10"),
654 vec(
"0 200 400 600 800 1200 1400 1800 2400 3000 3200 5000") * 1e-9);
666 set_channel_profile(vec(
"-3 0 -3 -5 -2 -4"),
667 vec(
"0 400 1000 1600 5000 6600") * 1e-9);
675 set_channel_profile(vec(
"-2.5 0 -3 -5 -2 -4"),
676 vec(
"0 300 1000 1600 5000 6600") * 1e-9);
684 set_channel_profile(vec(
"-7 -3 -1 0 -2 -6 -7 -1 -2 -7 -10 -15"),
685 vec(
"0 200 400 800 1600 2200 3200 5000 6000 7200 8200 10000") * 1e-9);
697 case COST207_BU12alt:
698 set_channel_profile(vec(
"-7.7 -3.4 -1.3 0 -2.3 -5.6 -7.4 -1.4 -1.6 -6.7 -9.8 -15.1"),
699 vec(
"0 100 300 700 1600 2200 3100 5000 6000 7200 8100 10000") * 1e-9);
713 set_channel_profile(vec(
"0 -2 -4 -7 -6 -12"),
714 vec(
"0 200 400 600 15000 17200") * 1e-9);
720 set_channel_profile(vec(
"0 -1.5 -4.5 -7.5 -8 -17.7"),
721 vec(
"0 100 300 500 15000 17200") * 1e-9);
727 set_channel_profile(vec(
"-10 -8 -6 -4 0 0 -4 -8 -9 -10 -12 -14"),
728 vec(
"0 200 400 600 800 2000 2400 15000 15200 15800 17200 20000") * 1e-9);
740 case COST207_HT12alt:
741 set_channel_profile(vec(
"-10 -8 -6 -4 0 0 -4 -8 -9 -10 -12 -14"),
742 vec(
"0 100 300 500 700 1000 1300 15000 15200 15700 17200 20000") * 1e-9);
758 for (
int i = 0; i < N_taps; i++)
759 tap_doppler_spectrum(i) = tap_spectrum[i];
764 tap_doppler_spectrum(tap_number) = tap_spectrum;
768 double relative_doppler)
771 "Channel_Specification::set_LOS(): Cannot set LOS component if not set channel profile");
772 it_assert((tap_number >= 0) && (tap_number < N_taps),
773 "Channel_Specification::set_LOS(): Tap number out of range");
774 it_assert((relative_doppler >= 0) && (relative_doppler <= 1.0),
775 "Channel_Specification::set_LOS(): Normalized Doppler out of range");
777 "Channel_Specification::set_LOS(): Rice factor out of range");
782 los_dopp(tap_number) = relative_doppler;
786 const vec& relative_doppler)
788 it_assert((relative_power.size() == N_taps),
789 "Channel_Specification::set_LOS(): Improper size of input vectors");
791 if (relative_doppler.size() == 0) {
792 los_power.set_size(relative_power.size());
793 los_dopp.set_size(relative_power.size());
794 for (
int i = 0; i < relative_power.size(); i++) {
796 "Channel_Specification::set_LOS(): Rice factor out of range");
802 it_assert(relative_doppler.size() == N_taps,
803 "Channel_Specification::set_LOS(): Improper size of input vectors");
804 los_power.set_size(relative_power.size());
805 los_dopp.set_size(relative_power.size());
806 for (
int i = 0; i < relative_power.size(); i++) {
807 it_assert((relative_doppler(i) >= 0) && (relative_doppler(i) <= 1.0),
808 "Channel_Specification::set_LOS(): Normalized Doppler out of range");
810 "Channel_Specification::set_LOS(): Rice factor out of range");
818 vec &delay_prof)
const 820 avg_power_dB = a_prof_dB;
826 it_assert((index >= 0) && (index < N_taps),
827 "Channel_Specification::get_doppler_spectrum(): Index of of range");
828 return tap_doppler_spectrum(index);
833 vec a_prof =
inv_dB(a_prof_dB);
834 return (a_prof * d_prof /
sum(a_prof));
839 vec a_prof =
inv_dB(a_prof_dB);
840 double a = a_prof * d_prof /
sum(a_prof);
841 double b = a_prof *
sqr(d_prof) /
sum(a_prof);
852 init_flag(false),
n_dopp(0.0), fading_type(Independent), method(Rice_MEDS),
853 filter_length(0), nrof_freq(16), discrete_Ts(0.0)
888 const ivec &delay_prof)
891 "TDL_Channel::set_channel_profile(): Minimum relative delay must be 0.");
892 it_assert(avg_power_dB.size() == delay_prof.size(),
893 "TDL_Channel::set_channel_profile(): Power and delay vectors must be of equal length!");
895 "TDL_Channel::set_channel_profile(): First tap must be at zero delay");
896 for (
int i = 1; i < delay_prof.size(); i++) {
897 it_assert(delay_prof(i) > delay_prof(i - 1),
898 "TDL_Channel::set_channel_profile(): Delays should be sorted and unique");
901 N_taps = delay_prof.size();
919 it_assert(no_taps >= 1,
"TDL_Channel::set_channel_profile_uniform(): Minimum number of taps is 1.");
921 vec avg_power_dB =
zeros(no_taps);
922 ivec delay_prof(no_taps);
923 for (
int i = 0; i < no_taps; i++)
931 it_assert(no_taps >= 1,
"TDL_Channel::set_channel_profile_exponential(): Minimum number of taps is 1.");
933 vec avg_power_dB(no_taps);
934 ivec delay_prof(no_taps);
935 for (
int i = 0; i < no_taps; i++) {
938 avg_power_dB(i) =
dB(
std::exp(static_cast<double>(-i)));
952 N_taps = avg_power_dB.size();
972 method = correlated_method;
985 it_assert((norm_doppler > 0) && (norm_doppler <= 1.0),
986 "TDL_Channel::set_norm_doppler(): Normalized Doppler out of range");
997 "TDL_Channel::set_LOS(): Improper size of input vectors");
999 if (relative_doppler.size() == 0) {
1000 los_power.set_size(relative_power.size());
1001 los_dopp.set_size(relative_power.size());
1002 for (
int i = 0; i < relative_power.size(); i++) {
1004 "TDL_Channel::set_LOS(): Rice factor out of range");
1006 los_dopp(i) = (relative_power(i) > 0) ? 0.7 : 0.0;
1011 "TDL_Channel::set_LOS(): Improper size of input vectors");
1012 los_power.set_size(relative_power.size());
1013 los_dopp.set_size(relative_power.size());
1014 for (
int i = 0; i < relative_power.size(); i++) {
1015 it_assert((relative_doppler(i) >= 0) && (relative_doppler(i) <= 1.0),
1016 "TDL_Channel::set_LOS(): Normalized Doppler out of range");
1018 "TDL_Channel::set_LOS(): Rice factor out of range");
1028 "TDL_Channel::set_LOS_power(): Improper size of input vector");
1030 los_power.set_size(relative_power.size());
1031 los_dopp.set_size(relative_power.size());
1032 for (
int i = 0; i <
los_power.size(); ++i) {
1034 los_dopp(i) = (relative_power(i) > 0) ? 0.7 : 0.0;
1042 "TDL_Channel::set_LOS_doppler(): Improper size of input vector");
1044 it_assert(
n_dopp > 0,
"TDL_Channel::set_LOS_doppler(): Normalized Doppler needs to be non zero to set the LOS Doppler in a Correlated fading generator");
1046 los_dopp.set_size(relative_doppler.size());
1047 for (
int i = 0; i < relative_doppler.size(); ++i) {
1048 it_assert((relative_doppler(i) >= 0) && (relative_doppler(i) <= 1.0),
1049 "TDL_Channel::set_LOS_doppler(): Normalized Doppler out of range");
1059 it_assert(
N_taps > 0,
"TDL_Channel::set_doppler_spectrum(): Channel profile not defined yet");
1061 it_assert(
n_dopp > 0,
"TDL_Channel::set_doppler_spectrum(): Normalized Doppler needs to be non zero to set the Doppler spectrum in the Correlated Rice MEDS fading generator");
1067 for (
int i = 0; i <
N_taps; i++)
1076 "TDL_Channel::set_doppler_spectrum(): Improper tap number");
1078 it_assert(
n_dopp > 0,
"TDL_Channel::set_doppler_spectrum(): Normalized Doppler needs to be non zero to set the Doppler spectrum in the Correlated Rice MEDS fading generator");
1091 it_assert(
n_dopp > 0,
"TDL_Channel::set_no_frequencies(): Normalized Doppler needs to be non zero to set the number of frequencies in the Correlated Rice MEDS fading generator");
1102 it_assert(
n_dopp > 0,
"TDL_Channel::set_filter_length(): Normalized Doppler needs to be non zero to use the Correlated FIR fading generator");
1114 it_assert(
n_dopp > 0,
"TDL_Channel::set_time_offset(): Normalized Doppler needs to be non zero to set time offset in a Correlated fading generator");
1119 for (
int i = 0; i <
N_taps; i++) {
1127 it_assert(
n_dopp > 0,
"TDL_Channel::shift_time_offset(): Normalized Doppler needs to be non zero to shift time offset in a Correlated fading generator");
1132 for (
int i = 0; i <
N_taps; i++) {
1133 fading_gen(i)->shift_time_offset(no_samples);
1139 ivec &delay_prof)
const 1173 it_assert(
N_taps > 0,
"TDL_Channel::init(): Channel profile not defined yet");
1175 "TDL_Channel::init(): LOS profile does not mach the channel profile");
1178 for (
int i = 0; i <
fading_gen.size(); i++) {
1191 for (
int i = 0; i <
N_taps; ++i) {
1200 for (
int i = 0; i <
N_taps; ++i) {
1210 "TDL_Channel::init(): Correlated fading requires non zero normalized Doppler");
1217 for (
int i = 0; i <
N_taps; ++i) {
1229 for (
int i = 0; i <
N_taps; ++i) {
1231 "TDL_Channel::init(): FIR fading generator can be used with Jakes spectrum only");
1244 for (
int i = 0; i <
N_taps; ++i) {
1246 "TDL_Channel::init(): IFFT fading generator can be used with Jakes spectrum only");
1257 it_error(
"TDL_Channel::init(): No such fading generation method");
1262 it_error(
"TDL_Channel::init(): No such fading type");
1274 for (
int i = 0; i <
N_taps; i++)
1283 channel_coeff.set_size(no_samples,
N_taps,
false);
1284 for (
int i = 0; i <
N_taps; i++)
1293 output.set_size(input.size() + maxdelay,
false);
1296 for (
int i = 0; i <
N_taps; i++)
1304 output.set_size(input.size() + maxdelay,
false);
1307 for (
int i = 0; i <
N_taps; i++)
1313 generate(input.size(), channel_coeff);
1319 generate(input.size(), channel_coeff);
1326 filter(input, output, channel_coeff);
1333 filter(input, output, channel_coeff);
1340 filter(input, output, channel_coeff);
1353 filter(input, output, channel_coeff);
1358 filter(input, output, channel_coeff);
1364 return filter(input, channel_coeff);
1369 return filter(input, channel_coeff);
1380 it_assert(
init_flag ==
true,
"calc_impulse_response: TDL_Channel is not initialized");
1381 it_assert(
N_taps == channel_coeff.
size(),
"calc_impulse_response: number of channel taps do not match");
1383 int no_samples = channel_coeff(0).
size();
1384 it_assert(no_samples > 0,
"calc_impulse_response: channel_coeff must contain samples");
1386 impulse_response.
set_size(no_samples);
1388 for (
int i = 0; i < no_samples; i++) {
1390 impulse_response(i).zeros();
1392 for (
int j = 0; j <
N_taps; j++)
1393 impulse_response(i)(
d_prof(j)) = channel_coeff(j)(i);
1400 it_assert(
init_flag ==
true,
"calc_frequency_response: TDL_Channel is not initialized");
1401 it_assert(
N_taps == channel_coeff.
size(),
"calc_frequency_response: number of channel taps do not match");
1403 int no_samples = channel_coeff(0).
size();
1404 it_assert(no_samples > 0,
"calc_frequency_response: channel_coeff must contain samples");
1406 frequency_response.
set_size(no_samples);
1408 it_assert(fft_size >
d_prof(
N_taps - 1),
"calc_frequency_response: fft_size must be larger than the maximum delay in samples");
1409 cvec impulse_response(fft_size);
1411 for (
int i = 0; i < no_samples; i++) {
1412 impulse_response.zeros();
1414 for (
int j = 0; j <
N_taps; j++)
1415 impulse_response(
d_prof(j)) = channel_coeff(j)(i);
1417 fft(impulse_response, frequency_response(i));
1424 it_assert(
init_flag ==
true,
"calc_frequency_response: TDL_Channel is not initialized");
1425 it_assert(
N_taps == channel_coeff.cols(),
"calc_frequency_response: number of channel taps do not match");
1427 int no_samples = channel_coeff.rows();
1428 it_assert(no_samples > 0,
"calc_frequency_response: channel_coeff must contain samples");
1430 frequency_response.set_size(fft_size, no_samples,
false);
1432 it_assert(fft_size >
d_prof(
N_taps - 1),
"calc_frequency_response: fft_size must be larger than the maximum delay in samples");
1433 cvec impulse_response(fft_size);
1436 for (
int i = 0; i < no_samples; i++) {
1437 impulse_response.zeros();
1439 for (
int j = 0; j <
N_taps; j++)
1440 impulse_response(
d_prof(j)) = channel_coeff(i, j);
1442 fft(impulse_response, freq);
1443 frequency_response.set_col(i, freq);
1449 it_assert(
N_taps > 0,
"TDL_Channel::discretize(): No channel profile specified");
1450 it_assert(delay_profile(0) == 0,
"TDL_Channel::discretize(): First tap should be at zero delay");
1454 "TDL_Channel:: discretize(): Channel profile lenghts must be equal to the number of taps");
1465 power(0) = p_prof(0);
1466 spower = p_prof(0) / (1 +
los_power(0));
1467 scattered(0) = spower;
1473 int j = 0, j_delay = 0;
1474 for (
int i = 1; i <
N_taps; i++) {
1475 if (delay_profile(i) > (j_delay + 0.5)*
discrete_Ts) {
1477 while (delay_profile(i) > (j_delay + 0.5)*
discrete_Ts) { j_delay++; }
1480 delay_prof(j) = j_delay;
1481 power(j) = p_prof(i);
1482 spower = p_prof(i) / (1 +
los_power(i));
1483 scattered(j) = spower;
1490 power(j) += p_prof(i);
1491 spower = p_prof(i) / (1 +
los_power(i));
1492 scattered(j) += spower;
1495 "TDL_Channel::discretize(): Sampling frequency too low. Can not discretize the channel with different Doppler spectra on merged taps.");
1496 it_warning(
"TDL_Channel::discretize(): Sampling frequency too low. Merging original tap " << i <<
" with new tap " << j <<
".");
1497 if (los_doppler(j) !=
los_dopp(i)) {
1498 los_doppler(j) = 0.7;
1499 it_warning(
"TDL_Channel::discretize(): LOS Doppler value reset to 0.7 for tap " << j <<
" due to the merging process.");
1504 int no_taps = j + 1;
1505 if (no_taps < N_taps) {
1506 delay_prof.set_size(no_taps,
true);
1507 power.set_size(no_taps,
true);
1508 direct.set_size(no_taps,
true);
1509 scattered.set_size(no_taps,
true);
1510 los_doppler.set_size(no_taps,
true);
1511 tap_spectrum.
set_size(no_taps,
true);
1531 int i,
length = input.length();
1532 bvec output(length);
1534 for (i = 0; i <
length; i++) {
1536 output(i) = input(i) +
bin(1);
1539 output(i) = input(i);
1552 int n = input.size();
1554 rng_cn.sample_vector(n, noise);
1562 int n = input.size();
1564 rng_n.sample_vector(n, noise);
vec los_dopp
Relative LOS Doppler for each Rice component.
Mat< Num_T > elem_div(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise division of two matrices.
void set_channel_profile(const vec &avg_power_dB, const vec &delay_prof)
Set both average power profile in dB and power delay profile in seconds.
CHANNEL_PROFILE
Predefined channel profiles. Includes LOS and Doppler spectrum settings.
Various functions on vectors and matrices - header file.
virtual void init()
Initialize the generator.
Rice_Fading_Generator(double norm_doppler, DOPPLER_SPECTRUM spectrum=Jakes, int no_freq=16, RICE_METHOD method=MEDS)
Default constructor.
General specification of a time-domain multipath channel.
const double m_2pi
Constant 2*Pi.
void calc_frequency_response(const Array< cvec > &channel_coeff, Array< cvec > &frequency_response, const int fft_size)
Calculate frequency-response on the supplied channel coefficients (produced by the generate() functio...
RICE_METHOD rice_method
Rice process generation method.
void set_coeffs(const Vec< T2 > &b)
Set the filter coefficients.
ITPP_EXPORT int round_i(double x)
Round to nearest integer.
RICE_METHOD
Rice fading generation methods: MEDS.
vec hamming(int n)
Hamming window.
int size() const
Returns the number of data elements in the array object.
bool init_flag
signals if generator is initialized or not
Definitions of window functions.
double randu(void)
Generates a random uniform (0,1) number.
virtual void set_norm_doppler(double norm_doppler)
Set normalized Doppler (for correlated fading generators)
virtual void set_time_offset(int offset)
Set time offset in samples (for correlated fading generators)
Vec< T > reverse(const Vec< T > &in)
Reverse the input vector.
virtual DOPPLER_SPECTRUM get_doppler_spectrum() const
Return Doppler spectrum (for Rice fading generator)
virtual void init()
Initialize the generator.
virtual double get_time_offset() const
Get time offset in samples (for correlated fading generators)
cvec operator()(const cvec &input)
Feed the complex input input through the complex-valued AWGN channel.
void shift_time_offset(int no_samples)
Shift fading generators' time offset. A Correlated fading type will be used.
void set_correlated_method(CORRELATED_METHOD method)
Set the fading generation method to method.
virtual void set_no_frequencies(int no_freq)
Set number of Doppler frequencies.
MA_Filter< std::complex< double >, double, std::complex< double > > fir_filter
Filter used for fading generation.
int ceil_i(double x)
The nearest larger integer.
Channel_Specification(const vec &avg_power_dB="0", const vec &delay_prof="0")
Default constructor (power profile in dB, delay profile in seconds)
void get_channel_profile(vec &avg_power_dB, ivec &delay_prof) const
Get both average power profile in dB and power delay profile in samples.
cvec left_overs
Left-overs from upsampling.
virtual void set_LOS_doppler(double relative_doppler)
Set relative Doppler of the LOS component (for correlated fading generators)
double discrete_Ts
Sampling time of discretization.
double norm(const cvec &v)
Calculate the 2-norm: norm(v)=sqrt(sum(abs(v).^2))
DOPPLER_SPECTRUM dopp_spectrum
Mat< Num_T > elem_mult(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise multiplication of two matrices.
vec log10(const vec &x)
log-10 of the elements
Rice type fading generator class.
double los_direct
Direct component: sqrt(los_power / (1 + los_power))
double erfinv(double P)
Inverse of error function.
ITPP_EXPORT void ifft(const cvec &in, cvec &out)
Inverse Fast Fourier Transform.
void set_channel_profile(const vec &avg_power_dB, const ivec &delay_prof)
Set both average power profile in dB and power delay profile in samples.
Definitions of Bessel functions.
T sum(const Vec< T > &v)
Sum of all elements in the vector.
Fading_Generator()
Default constructor.
void generate(int no_samples, Array< cvec > &channel_coeff)
Generate no_samples values of the channel.
DOPPLER_SPECTRUM
Predefined Doppler spectra.
ITPP_EXPORT void fft(const cvec &in, cvec &out)
Fast Fourier Transform.
double calc_rms_delay_spread() const
Calculate RMS delay spread in samples.
double get_time_offset() const
Get fading generators' time ofset.
virtual RICE_METHOD get_rice_method() const
Get calculation method of Doppler frequencies and amplitudes (for Rice fading generator) ...
#define it_assert(t, s)
Abort if t is not true.
int length(const Vec< T > &v)
Length of vector.
FADING_TYPE
Fading generator type: Independent (default), Static or Correlated.
void set_filter_length(int filter_length)
Set fading generator filter length. FIR method will be used.
double dB(double x)
Decibel of x (10*log10(x))
virtual void generate(int no_samples, cvec &output)
Generate no_samples values from the fading process.
Minimum and maximum functions on vectors and matrices.
CORRELATED_METHOD
Correlated fading generation methods: Rice_MEDS (default), IFFT or FIR.
virtual void set_no_frequencies(int no_freq)
Set number of sine frequencies (for Rice fading generator)
Error functions - header file.
void set_size(int n, bool copy=false)
Resizing an Array<T>.
vec get_LOS_power() const
Get relative power (Rice factor) for each tap.
double calc_mean_excess_delay() const
Calculate mean excess delay in samples.
virtual ~TDL_Channel()
Destructor.
void init()
Initialize all fading generators. Automatically invoked in generate() or filter() functions...
ITPP_EXPORT cvec zeros_c(int size)
A Double Complex vector of zeros.
vec sin(const vec &x)
Sine function.
ITPP_EXPORT vec zeros(int size)
A Double vector of zeros.
Static fading generator class.
T sum_sqr(const Vec< T > &v)
Sum of square of the elements in a vector.
Communication channels' classes - header file.
vec a_prof
Average amplitude of each tap.
T min(const Vec< T > &in)
Minimum value of vector.
void set_doppler_spectrum(DOPPLER_SPECTRUM *tap_spectrum)
Set doppler spectrum for each tap in the channel profile.
virtual double get_norm_doppler() const
Return normalized Doppler (for correlated fading generators)
int nrof_freq
Number of sine frequencies in the Rice MEDS fading generator.
const double pi
Constant Pi.
virtual void set_doppler_spectrum(DOPPLER_SPECTRUM spectrum)
Set Doppler spectrum.
Array< DOPPLER_SPECTRUM > get_doppler_spectrum() const
Get doppler spectrum for tap index.
double los_power
Relative power of LOS component compared to diffuse component (K factor)
vec exp(const vec &x)
Exp of the elements of a vector x.
ivec d_prof
Delay in samples for each tap.
vec los_power
Relative power for each Rice component.
virtual void generate(int no_samples, cvec &output)
Generate no_samples values from the fading process.
T max(const Vec< T > &v)
Maximum value of vector.
Trigonometric and hyperbolic functions - header file.
int pow2i(int x)
Calculate two to the power of x (2^x); x is integer.
void set_channel_profile_uniform(int no_taps)
Set channel profile to uniform with no_taps taps.
void operator()(const cvec &input, cvec &output, Array< cvec > &channel_coeff)
Generate channel coefficients and filter the input. Return output and channel coefficients.
double inv_dB(double x)
Inverse of decibel of x.
void calc_impulse_response(const Array< cvec > &channel_coeff, Array< cvec > &impulse_response)
Calculate impulse-response on the supplied channel coefficients (produced by the generate() function)...
int filter_length
Filter length of FIR fading generator.
void set_LOS_power(const vec &relative_power)
Set LOS power for each tap. LOS Doppler will be set to 0.7 by default.
vec pow(const double x, const vec &y)
Calculates x to the power of y (x^y)
vec to_vec(const Vec< T > &v)
Converts a Vec<T> to vec.
int Ni
Number of sine waves in a Gaussian process.
virtual void set_rice_method(RICE_METHOD method)
Set calculation method of Doppler frequencies and amplitudes (for Rice fading generator) ...
FIR type Fading generator class.
void set_fading_type(FADING_TYPE fading_type)
Set fading type to one of Independent, Static or Correlated.
bool init_flag
Channel ready to produce data.
void filter(const cvec &input, cvec &output, Array< cvec > &channel_coeff)
Generate channel coefficients and filter the input. Return output and channel coefficients.
void set_LOS(int tap_number, double relative_power, double relative_doppler=0.7)
Set LOS (Rice) components for tap tap_number.
vec spectrum(const vec &v, int nfft, int noverlap)
Power spectrum calculation.
void set_LOS_power(double relative_power)
Set relative LOS power.
virtual void set_filter_length(int filter_length)
Set FIR filter length.
vec get_LOS_doppler() const
Get relative Doppler for each tap.
void set_time_offset(int offset)
Set fading generators' time offset in samples. A Correlated fading type will be used.
IFFT type Fading generator class.
virtual void generate(int no_samples, cvec &output)=0
Generate no_samples values from the fading process.
ITPP_EXPORT vec ones(int size)
A float vector of ones.
Resampling functions - header file.
Miscellaneous statistics functions and classes - header file.
FIR_Fading_Generator(double norm_doppler, int filter_length=500)
Default constructor.
void set_doppler_spectrum(const DOPPLER_SPECTRUM *tap_spectrum)
Set doppler spectrum for each tap in the channel profile. Rice_MEDS method will be used...
virtual int get_filter_length() const
Set FIR filter length (for FIR fading generator)
void set_channel_profile_exponential(int no_taps)
Set channel profile to exponential with no_taps taps.
virtual void set_filter_length(int filter_length)
Set FIR filter length (for FIR fading generator)
virtual void shift_time_offset(int no_samples)
Shift generator time offset by a number of samples (for correlated fading generators) ...
void set_no_frequencies(int no_freq)
Set number of sine frequencies. Rice_MEDS method will be used.
void filter_known_channel(const cvec &input, cvec &output, const Array< cvec > &channel_coeff)
Filter the input with the known channel values channel_coeff (e.g. from the generate function) ...
void init_MEDS()
Init function for MEDS method.
void discretize(const vec &delay_profile)
Discretize the delay profile with discrete_Ts (Ts). All taps within ((i-0.5)Ts,(i+0.5)Ts] belong to the ith discrete tap.
void set_norm_doppler(double norm_doppler)
Set normalized Doppler rate. A Correlated fading type will be used.
virtual void init()
Initialize the generator.
vec sqr(const cvec &data)
Absolute square of elements.
Definitions of special vectors and matrices.
#define it_warning(s)
Display a warning message.
virtual int get_no_frequencies() const
Get number of sine frequencies (for Rice fading generator)
vec linspace(double from, double to, int points)
linspace (works in the same way as the MATLAB version)
void set_LOS_doppler(const vec &relative_doppler)
Set LOS doppler for each tap. A Correlated fading type will be used.
virtual double get_LOS_doppler() const
Get relative Doppler of the LOS component (for correlated fading generators)
virtual void init()=0
Initialize the generator.
vec get_avg_power_dB() const
Return power profile in dB.
Independent (random) fading generator class.
Binary arithmetic (boolean) class.
TDL_Channel(const vec &avg_power_dB="0", const ivec &delay_prof="0")
Default constructor.
#define it_error(s)
Abort unconditionally.
void generate_Jakes(int no_samples, cvec &output)
Generator for Jakes spectrum.
double n_dopp
Normalized Doppler of the correlated fading.
vec sqrt(const vec &x)
Square root of the elements.
virtual void generate(int no_samples, cvec &output)
Generate no_samples values from the fading process.
Array< DOPPLER_SPECTRUM > tap_doppler_spectrum
Doppler spectrum for each tap.
void get_channel_profile(vec &avg_power_dB, vec &delay_prof) const
Get both average power profile in dB and power delay profile in seconds.
double calc_mean_excess_delay() const
Calculate mean excess delay in samples.
double calc_rms_delay_spread() const
Calculate RMS delay spread in samples.
bvec operator()(const bvec &input)
Feed input through the BSC channel.
virtual void generate(int no_samples, cvec &output)
Generate no_samples values from the fading process.
int N_taps
Number of taps.
vec cos(const vec &x)
Cosine function.
Array< Fading_Generator * > fading_gen
Fading generators for each tap.
double besselj(int nu, double x)
Bessel function of first kind of order nu for nu integer.
virtual void set_doppler_spectrum(DOPPLER_SPECTRUM spectrum)
Set Doppler spectrum (for Rice fading generator)
virtual void generate(int no_samples, cvec &output)
Generate no_samples values from the fading process.
void set_LOS(const vec &relative_power, const vec &relative_doppler="")
Set LOS parameters for each tap. LOS Doppler will be set to 0.7 by default.
FADING_TYPE fading_type
Fading type: Independent (default), Static or Correlated.
CORRELATED_METHOD method
Correlated fading generation method: Rice_MEDS (default), IFFT or FIR.
int levels2bits(int n)
Calculate the number of bits needed to represent n different values (levels).
double los_diffuse
Diffuse component: sqrt(1 / (1 + los_power))
virtual void set_rice_method(RICE_METHOD method)
Set calculation method of Doppler frequencies and amplitudes.
vec Jakes_filter(double norm_dopp, int order=100)
Jakes spectrum filter.
int fir_length
Size of FIR filter.
std::complex< double > randn_c(void)
Generates a random complex Gaussian (0,1) variable.
const Array< T > concat(const Array< T > &a, const T &e)
Append element e to the end of the Array a.