00001
00029 #ifndef CHANNEL_H
00030 #define CHANNEL_H
00031
00032 #include <itpp/base/math/elem_math.h>
00033 #include <itpp/base/mat.h>
00034 #include <itpp/base/array.h>
00035 #include <itpp/base/random.h>
00036 #include <itpp/signal/filter.h>
00037
00184 namespace itpp
00185 {
00186
00188
00189
00191 enum CHANNEL_PROFILE {
00192 ITU_Vehicular_A, ITU_Vehicular_B, ITU_Pedestrian_A, ITU_Pedestrian_B,
00193 COST207_RA, COST207_RA6,
00194 COST207_TU, COST207_TU6alt, COST207_TU12, COST207_TU12alt,
00195 COST207_BU, COST207_BU6alt, COST207_BU12, COST207_BU12alt,
00196 COST207_HT, COST207_HT6alt, COST207_HT12, COST207_HT12alt,
00197 COST259_TUx, COST259_RAx, COST259_HTx
00198 };
00199
00201 enum FADING_TYPE { Independent, Static, Correlated };
00202
00204 enum CORRELATED_METHOD { Rice_MEDS, IFFT, FIR };
00205
00207 enum RICE_METHOD { MEDS };
00208
00210 enum DOPPLER_SPECTRUM {
00211 Jakes = 0, J = 0, Classic = 0, C = 0,
00212 GaussI = 1, Gauss1 = 1, GI = 1, G1 = 1,
00213 GaussII = 2, Gauss2 = 2, GII = 2, G2 = 2
00214 };
00215
00216
00226 class Fading_Generator
00227 {
00228 public:
00230 Fading_Generator();
00232 virtual ~Fading_Generator() {}
00233
00235 void set_LOS_power(double relative_power);
00237 virtual void set_LOS_doppler(double relative_doppler);
00239 virtual void set_time_offset(int offset);
00241 virtual void set_filter_length(int filter_length);
00243 virtual void set_norm_doppler(double norm_doppler);
00245 virtual void set_doppler_spectrum(DOPPLER_SPECTRUM spectrum);
00247 virtual void set_no_frequencies(int no_freq);
00249 virtual void set_rice_method(RICE_METHOD method);
00250
00252 double get_LOS_power() const { return los_power; }
00254 virtual double get_LOS_doppler() const;
00256 virtual double get_time_offset() const;
00258 virtual int get_filter_length() const;
00260 virtual double get_norm_doppler() const;
00262 virtual DOPPLER_SPECTRUM get_doppler_spectrum() const;
00264 virtual int get_no_frequencies() const;
00266 virtual RICE_METHOD get_rice_method() const;
00267
00269 virtual void shift_time_offset(int no_samples);
00270
00272 virtual void init() = 0;
00273
00275 virtual void generate(int no_samples, cvec &output) = 0;
00277 cvec generate(int no_samples);
00278
00279 protected:
00280 bool init_flag;
00281 double los_power;
00282 double los_diffuse;
00283 double los_direct;
00284 };
00285
00286
00295 class Independent_Fading_Generator : public Fading_Generator
00296 {
00297 public:
00299 Independent_Fading_Generator() : Fading_Generator() {}
00301 virtual ~Independent_Fading_Generator() {}
00302
00304 virtual void init() { init_flag = true; }
00305
00306 using Fading_Generator::generate;
00307
00309 virtual void generate(int no_samples, cvec& output);
00310 };
00311
00312
00322 class Static_Fading_Generator : public Fading_Generator
00323 {
00324 public:
00326 Static_Fading_Generator() : Fading_Generator() {}
00328 virtual ~Static_Fading_Generator() {}
00329
00331 virtual void init();
00332
00333 using Fading_Generator::generate;
00334
00336 virtual void generate(int no_samples, cvec& output);
00337
00338 protected:
00340 std::complex<double> static_sample;
00341 };
00342
00343
00356 class Correlated_Fading_Generator : public Fading_Generator
00357 {
00358 public:
00360 Correlated_Fading_Generator(double norm_doppler);
00362 virtual ~Correlated_Fading_Generator() {}
00363
00365 virtual void set_norm_doppler(double norm_doppler);
00367 virtual void set_LOS_doppler(double relative_doppler);
00369 virtual void set_time_offset(int offset);
00370
00372 virtual double get_norm_doppler() const { return n_dopp; }
00374 virtual double get_LOS_doppler() const { return los_dopp; }
00376 virtual double get_time_offset() const { return time_offset; }
00377
00379 virtual void shift_time_offset(int no_samples);
00380
00382 virtual void init() = 0;
00383
00384 using Fading_Generator::generate;
00385
00387 virtual void generate(int no_samples, cvec& output) = 0;
00388
00389 protected:
00390 double n_dopp;
00391 double los_dopp;
00392 double time_offset;
00393
00395 void add_LOS(int idx, std::complex<double>& sample);
00396 };
00397
00398
00433 class Rice_Fading_Generator : public Correlated_Fading_Generator
00434 {
00435 public:
00437 Rice_Fading_Generator(double norm_doppler, DOPPLER_SPECTRUM spectrum = Jakes,
00438 int no_freq = 16, RICE_METHOD method = MEDS);
00440 virtual ~Rice_Fading_Generator() {}
00441
00443 virtual void set_doppler_spectrum(DOPPLER_SPECTRUM spectrum);
00445 virtual void set_no_frequencies(int no_freq);
00447 virtual void set_rice_method(RICE_METHOD method);
00448
00450 virtual DOPPLER_SPECTRUM get_doppler_spectrum() const { return dopp_spectrum; }
00452 virtual int get_no_frequencies() const { return Ni; }
00454 virtual RICE_METHOD get_rice_method() const { return rice_method; }
00455
00457 virtual void init();
00458
00459 using Correlated_Fading_Generator::generate;
00460
00462 virtual void generate(int no_samples, cvec &output);
00463
00464 protected:
00465 DOPPLER_SPECTRUM dopp_spectrum;
00466
00467 int Ni;
00469 RICE_METHOD rice_method;
00472 vec f1, f2, c1, c2, th1, th2;
00476 double f01, f02;
00479
00480 void init_MEDS();
00481 };
00482
00483
00502 class FIR_Fading_Generator : public Correlated_Fading_Generator
00503 {
00504 public:
00506 FIR_Fading_Generator(double norm_doppler, int filter_length = 500);
00508 virtual ~FIR_Fading_Generator() {}
00509
00511 virtual void set_filter_length(int filter_length);
00513 virtual int get_filter_length() const { return fir_length; }
00514
00516 virtual void init();
00517
00518 using Correlated_Fading_Generator::generate;
00519
00521 virtual void generate(int no_samples, cvec &output);
00522
00523 protected:
00524 int fir_length;
00525 int upsample_rate;
00526
00527 MA_Filter<std::complex<double>, double, std::complex<double> > fir_filter;
00528 cvec left_overs;
00529
00540 vec Jakes_filter(double norm_dopp, int order = 100);
00541 };
00542
00543
00568 class IFFT_Fading_Generator : public Correlated_Fading_Generator
00569 {
00570 public:
00572 IFFT_Fading_Generator(double norm_doppler) :
00573 Correlated_Fading_Generator(norm_doppler) {}
00575 virtual ~IFFT_Fading_Generator() {}
00576
00578 virtual void init() { init_flag = true; }
00579
00580 using Correlated_Fading_Generator::generate;
00581
00583 virtual void generate(int no_samples, cvec &output);
00584
00585 protected:
00587 void generate_Jakes(int no_samples, cvec &output);
00588 };
00589
00590
00662 class Channel_Specification
00663 {
00664 public:
00666 Channel_Specification(const vec &avg_power_dB = "0", const vec &delay_prof = "0");
00668 Channel_Specification(const CHANNEL_PROFILE profile);
00670 virtual ~Channel_Specification() {}
00671
00673 void set_channel_profile(const vec &avg_power_dB, const vec &delay_prof);
00675 void set_channel_profile(const CHANNEL_PROFILE profile);
00676
00678 void set_doppler_spectrum(DOPPLER_SPECTRUM *tap_spectrum);
00680 void set_doppler_spectrum(int tap_number, DOPPLER_SPECTRUM tap_spectrum);
00681
00683 void set_LOS(int tap_number, double relative_power, double relative_doppler = 0.7);
00685 void set_LOS(const vec& relative_power, const vec& relative_doppler = "");
00686
00688 void get_channel_profile(vec &avg_power_dB, vec &delay_prof) const;
00690 vec get_avg_power_dB() const { return a_prof_dB; }
00692 vec get_delay_prof() const { return d_prof; }
00694 Array<DOPPLER_SPECTRUM> get_doppler_spectrum() const { return tap_doppler_spectrum; }
00696 DOPPLER_SPECTRUM get_doppler_spectrum(int index) const;
00698 vec get_LOS_power() const { return los_power; }
00700 vec get_LOS_doppler() const { return los_dopp; }
00702 double get_LOS_power(int tap_number) const { return los_power(tap_number); }
00704 double get_LOS_doppler(int tap_number) const { return los_dopp(tap_number); }
00705
00707 int taps() const { return N_taps; }
00708
00710 double calc_mean_excess_delay() const;
00712 double calc_rms_delay_spread() const;
00713
00714 protected:
00715 vec a_prof_dB;
00716 vec d_prof;
00717 Array<DOPPLER_SPECTRUM> tap_doppler_spectrum;
00718 int N_taps;
00719 vec los_power;
00720 vec los_dopp;
00721 };
00722
00723
00823 class TDL_Channel
00824 {
00825 public:
00827 TDL_Channel(const vec &avg_power_dB = "0", const ivec &delay_prof = "0");
00829 TDL_Channel(const Channel_Specification &channel_spec, double sampling_time);
00831 virtual ~TDL_Channel();
00832
00834 void set_channel_profile(const vec &avg_power_dB, const ivec &delay_prof);
00836 void set_channel_profile_uniform(int no_taps);
00838 void set_channel_profile_exponential(int no_taps);
00840 void set_channel_profile(const Channel_Specification &channel_spec, double sampling_time);
00841
00843 void set_correlated_method(CORRELATED_METHOD method);
00845 void set_fading_type(FADING_TYPE fading_type);
00846
00848 void set_norm_doppler(double norm_doppler);
00849
00851 void set_LOS(const vec& relative_power, const vec& relative_doppler = "");
00853 void set_LOS_power(const vec& relative_power);
00855 void set_LOS_doppler(const vec& relative_doppler);
00856
00858 void set_doppler_spectrum(const DOPPLER_SPECTRUM *tap_spectrum);
00860 void set_doppler_spectrum(int tap_number, DOPPLER_SPECTRUM tap_spectrum);
00862 void set_no_frequencies(int no_freq);
00863
00865 void set_time_offset(int offset);
00867 void shift_time_offset(int no_samples);
00868
00870 void set_filter_length(int filter_length);
00871
00872
00874 int taps() const { return N_taps; }
00875
00877 void get_channel_profile(vec &avg_power_dB, ivec &delay_prof) const;
00879 vec get_avg_power_dB() const;
00881 ivec get_delay_prof() const { return d_prof; }
00882
00884 CORRELATED_METHOD get_correlated_method() const { return method; }
00886 FADING_TYPE get_fading_type() const { return fading_type; }
00887
00889 double get_norm_doppler() const { return n_dopp; }
00890
00892 vec get_LOS_power() const { return los_power; }
00894 vec get_LOS_doppler() const { return los_dopp; }
00896 double get_LOS_power(int tap_number) const { return los_power(tap_number); }
00898 double get_LOS_doppler(int tap_number) const { return los_dopp(tap_number); }
00899
00901 int get_no_frequencies() const { return nrof_freq; }
00902
00904 double get_time_offset() const;
00905
00907 double calc_mean_excess_delay() const;
00909 double calc_rms_delay_spread() const;
00910
00912 void init();
00913
00915 void generate(int no_samples, Array<cvec> &channel_coeff);
00917 void generate(int no_samples, cmat &channel_coeff);
00918
00920 void filter_known_channel(const cvec &input, cvec &output, const Array<cvec> &channel_coeff);
00922 void filter_known_channel(const cvec &input, cvec &output, const cmat &channel_coeff);
00923
00925 void filter(const cvec &input, cvec &output, Array<cvec> &channel_coeff);
00927 void filter(const cvec &input, cvec &output, cmat &channel_coeff);
00929 cvec filter(const cvec &input, Array<cvec> &channel_coeff);
00931 cvec filter(const cvec &input, cmat &channel_coeff);
00933 void filter(const cvec &input, cvec &output);
00935 cvec filter(const cvec &input);
00936
00938 void operator()(const cvec &input, cvec &output, Array<cvec> &channel_coeff);
00940 void operator()(const cvec &input, cvec &output, cmat &channel_coeff);
00942 cvec operator()(const cvec &input, Array<cvec> &channel_coeff);
00944 cvec operator()(const cvec &input, cmat &channel_coeff);
00946 cvec operator()(const cvec &input);
00947
00949 void calc_impulse_response(const Array<cvec> &channel_coeff, Array<cvec> &impulse_response);
00950
00952 void calc_frequency_response(const Array<cvec> &channel_coeff, Array<cvec> &frequency_response, const int fft_size);
00954 void calc_frequency_response(const cmat &channel_coeff, cmat &frequency_response, const int fft_size);
00956 double get_sampling_time() const { return discrete_Ts; }
00957
00958 protected:
00959 bool init_flag;
00960 vec a_prof;
00961 ivec d_prof;
00962 vec los_power;
00963 vec los_dopp;
00964 int N_taps;
00965 double n_dopp;
00966 FADING_TYPE fading_type;
00967 CORRELATED_METHOD method;
00968 Array<DOPPLER_SPECTRUM> tap_doppler_spectrum;
00969 Array<Fading_Generator *> fading_gen;
00970 int filter_length;
00971 int nrof_freq;
00972 double discrete_Ts;
00973
00980 void discretize(const vec &delay_profile);
00981 };
00982
00983
00984
01003 class BSC
01004 {
01005 public:
01007 BSC(double in_p = 0.0) : u(0.0, 1.0) { p = in_p; };
01009 void set_prob(double in_p) { p = in_p; };
01011 double get_prob() const { return p; };
01013 bvec operator()(const bvec &input);
01014 private:
01015 Uniform_RNG u;
01016 double p;
01017 };
01018
01019
01020
01054 class AWGN_Channel
01055 {
01056 public:
01058 AWGN_Channel(double noisevar = 0.0): sigma(std::sqrt(noisevar)) {}
01060 void set_noise(double noisevar) { sigma = std::sqrt(noisevar); }
01062 double get_noise() const { return sqr(sigma); }
01064 cvec operator()(const cvec &input);
01066 vec operator()(const vec &input);
01067 private:
01068 Complex_Normal_RNG rng_cn;
01069 Normal_RNG rng_n;
01070 double sigma;
01071 };
01072
01074
01075 }
01076
01077 #endif // #ifndef CHANNEL_H