00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00030 #ifndef MIMO_CHANNEL_H
00031 #define MIMO_CHANNEL_H
00032
00033 #include <iostream>
00034 #include <fstream>
00035 #include <complex>
00036
00037 #include <simthetic/phbib.h>
00038 #include <simthetic/phrand.h>
00039 #include <simthetic/signals.h>
00040 #include <simthetic/basicdevice.h>
00041 #include <simthetic/interfaces.h>
00042
00043 using namespace simth;
00044
00045 #include "matrixseq.h"
00046
00047
00048
00049
00052 namespace mimo {
00053
00054 const double DELAY_THRESHOLD = 0.001;
00055
00056
00057 class MIMOChannel;
00058
00059 std::ostream& operator<<(std::ostream &os, const MIMOChannel &cha);
00060
00068 class MIMOChannel : public Device
00069 {
00070 private:
00072 double noise;
00073
00076 GaussRng *gauss;
00077
00078 protected:
00079 size_t nr_tx;
00080 size_t nr_rx;
00081
00083 MatrixFreqSignal::storage_type transfer;
00084
00085
00087 double getGauss() const { return gauss->get_inl();}
00088
00091 void addNoise(VectorTimeSignal::reference v) const;
00092
00093 const bool diagonal;
00094
00095
00096 void assert_vector_lengths(const VectorTimeSignal &in,
00097 const VectorTimeSignal &out) const;
00098
00099 void assert_transfer_lengths(const MatrixFreqSignal::storage_type& our,
00100 const MatrixFreqSignal& next) const;
00101
00102 void assert_transfer_dim(const MatrixFreqSignal::storage_type& our,
00103 const MatrixFreqSignal& next) const;
00104
00105 public:
00106
00115 MIMOChannel(int id,
00116 DeviceSystemIntf* s,
00117 const simth::PropertyList& pl);
00118
00121 virtual ~MIMOChannel() {delete gauss;}
00122
00125 void setNoisePower(double n);
00126
00130 void setSNR(double snr);
00131
00134 double getNoisePower() const { return noise; }
00135
00146 virtual void getTransfer(int relative_time,
00147 MatrixFreqSignal& trans) const =0;
00148
00151 virtual void transmit(const VectorTimeSignal &sym,
00152 VectorTimeSignal& outsym) =0;
00153
00154 virtual void updateInputLengths();
00155 virtual void updateOutputLengths();
00156
00157 virtual void process();
00158
00159 virtual void print(std::ostream &os) const ;
00160
00161 virtual void startOfSimulation();
00162
00163 static void init(const std::string& fileName,
00164 Device** dev, DeviceSystemIntf* sysPtr, int ID,
00165 const std::string& regionQualifier = "");
00166 };
00167
00168
00169
00170
00171
00172
00173 class PerfectMIMOChannel : public MIMOChannel
00174 {
00175
00176 public:
00177 PerfectMIMOChannel(int deviceID,
00178 DeviceSystemIntf* system,
00179 const simth::PropertyList& pl)
00180 : MIMOChannel(deviceID, system, pl) {}
00181
00183 void getTransfer(int relative_time, MatrixFreqSignal& trans) const;
00184
00186 void transmit(const VectorTimeSignal &sym, VectorTimeSignal& outsym);
00187 void print(std::ostream &os) const;
00188 };
00189
00190
00191
00192
00194 class AWGNMIMOChannel : public MIMOChannel
00195 {
00196 public:
00198 AWGNMIMOChannel(int deviceID,
00199 DeviceSystemIntf* system,
00200 const simth::PropertyList& pl)
00201 : MIMOChannel(deviceID, system, pl) {}
00202
00204 virtual ~AWGNMIMOChannel() {}
00205
00206
00207 void getTransfer(int relative_time,
00208 MatrixFreqSignal& trans) const;
00209
00211 void transmit(const VectorTimeSignal &sym, VectorTimeSignal& outsym);
00212
00213 virtual void print(std::ostream &os) const;
00214 };
00215
00216
00217 inline void AWGNMIMOChannel::print(std::ostream &os) const
00218 {
00219
00220 std::ios::fmtflags oldSettings = os.flags();
00221 MIMOChannel::print(os);
00222 os.width(15);
00223 os<<std::endl<<"# channel type: AWGN cannel";
00224 os.setf(oldSettings);
00225 }
00226
00227
00228
00229
00232 class AntennaArray {
00233
00234 public:
00235 virtual ~AntennaArray() {};
00238 virtual mimo::CVector get_steeringVector(size_t N, double alpha) const;
00239
00243 virtual double get_phase(unsigned N, unsigned k, double alpha) const = 0;
00244
00250 static AntennaArray *init(const simth::PropertyList& pl,
00251 const char *propertyname = "array_geometry");
00252
00254 static mimo::CVector unitVector(size_t n, size_t N);
00255
00256 };
00257
00260 class UniformLinearLambdaHalf : public AntennaArray
00261 {
00262 public:
00263 virtual ~UniformLinearLambdaHalf() {};
00267 double get_phase(unsigned N, unsigned k, double alpha) const;
00268 };
00269
00273 class UniformCircularLambdaHalf : public AntennaArray
00274 {
00275 public:
00276 virtual ~UniformCircularLambdaHalf() {};
00280 double get_phase(unsigned N, unsigned k, double alpha) const;
00281 };
00282
00287 class NonUniform : public AntennaArray
00288 {
00289 unsigned nr;
00290 std::vector<double> spacings;
00291 public:
00295 NonUniform(const std::string& filename, unsigned N);
00296 virtual ~NonUniform() {};
00297
00301 double get_phase(unsigned N, unsigned k, double alpha) const;
00302 };
00303
00304 }
00305
00307
00308
00309
00310 #endif