![]() |
four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
|
00001 // Copyright 2011-2013, Per Zetterberg, KTH Royal Institute of Technology 00002 // 00003 // This program is free software: you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation, either version 3 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00015 // 00016 00017 00018 #include "LDPC1.hpp" 00019 #include "AMC.hpp" 00020 #include <itpp/itcomm.h> 00021 #include <iostream> 00022 #include <fstream> 00023 #include <math.h> 00024 #include <cmath> 00025 #include <string> 00026 #include <unistd.h> 00027 00028 using namespace itpp; 00029 using namespace std; 00030 00031 AMC::AMC(void) {}; 00032 00033 void AMC::init(uint32_t code_word_size,bool load_from_file) { 00034 00035 b0.init(0.25,code_word_size,10,load_from_file,"code_data1.it"); 00036 b1.init(0.5,code_word_size,10,load_from_file,"code_data2.it"); 00037 b2.init(0.625,code_word_size,10,load_from_file,"code_data3.it"); 00038 b3.init(0.75,code_word_size,10,load_from_file,"code_data4.it"); 00039 00040 m_code_word_size=code_word_size; 00041 00042 soft_bit.set_length(code_word_size); 00043 only_raw_bits=false; 00044 }; 00045 00046 int AMC::codec_message_size(uint32_t codec_ix) { 00047 return codec(codec_ix)->message_length(); 00048 } 00049 00050 void AMC::encode(uint32_t codec_ix, bvec message, bvec &transmitted) { 00051 codec(codec_ix)->chan_encode(message,transmitted); 00052 }; 00053 00054 void AMC::modulate(uint32_t modulation_order, uint32_t codec_ix, bvec message, bvec &transmitted, cvec &symbols,int skip_symbols) { 00055 ivec ti(1); 00056 cvec ci(1); 00057 00058 qam.set_M(modulation_order); 00059 codec(codec_ix)->chan_encode(message,transmitted); 00060 00061 int f=qam.bits_per_symbol(); 00062 ivec b2s=qam.get_bits2symbols(); 00063 int symbol_index; 00064 00065 for (int i1=0;i1<transmitted.length()/f;i1++) { 00066 00067 symbol_index=b2s(bin2dec(transmitted(i1*f,i1*f+f-1))); 00068 ti(0)=symbol_index; 00069 qam.modulate(ti,ci); 00070 symbols(i1+skip_symbols)=ci(0); 00071 00072 }; 00073 00074 00075 }; 00076 00077 00078 double AMC::evm(uint32_t modulation_order, bvec &transmitted, cvec &symbols, int skip_symbols) { 00079 ivec ti(1); 00080 cvec ci(1); 00081 double evm=0.0; 00082 ivec b2s=qam.get_bits2symbols(); 00083 int symbol_index; 00084 00085 qam.set_M(modulation_order); 00086 int f=qam.bits_per_symbol(); 00087 00088 for (int i1=0;i1<transmitted.length()/f;i1++) { 00089 symbol_index=b2s(bin2dec(transmitted(i1*f,i1*f+f-1))); 00090 ti(0)=symbol_index; 00091 qam.modulate(ti,ci); 00092 evm+=sqr(symbols(i1+skip_symbols)-ci(0)); 00093 00094 }; 00095 evm/=(transmitted.length()/f); 00096 evm=sqrt(evm); 00097 return evm; 00098 00099 }; 00100 00101 00102 00103 void AMC::demodulate(const cvec &input_symbols, double noise_variance, uint32_t modulation_order, uint32_t codec_ix, bvec &message_hat, bvec &transmitted_hat) 00104 { 00105 00106 qam.set_M(modulation_order); 00107 for (int i1=1;i1<=log2(modulation_order);i1++) { 00108 soft_bit(m_code_word_size-1)=0; 00109 }; 00110 00111 qam.demodulate_soft_bits(input_symbols,noise_variance,soft_bit); 00112 00113 transmitted_hat=soft_bit<0; 00114 00115 if (!only_raw_bits) { 00116 codec(codec_ix)->chan_decode(soft_bit,message_hat); 00117 }; 00118 00119 }; 00120 00121 double AMC::noise_variance(const cvec &symbols, uint32_t modulation_order){ 00122 00123 QAM modulation; 00124 double noise_variance_norm; 00125 cvec closest_constellation_point(1); 00126 cvec symbol(1); 00127 00128 modulation.set_M(modulation_order); 00129 00130 // Estimate noise variance in symbols 00131 noise_variance_norm=0; 00132 for (int i1=0;i1<symbols.length();i1++) { 00133 symbol=symbols(i1); 00134 closest_constellation_point=modulation.modulate_bits( 00135 modulation.demodulate_bits(symbol)); 00136 00137 00138 noise_variance_norm+=sum(sqr(symbol-closest_constellation_point)); 00139 }; 00140 noise_variance_norm/=symbols.length(); 00141 if (noise_variance_norm<1e-3) 00142 noise_variance_norm=1e-3; 00143 00144 return noise_variance_norm; 00145 } 00146 00147 00148 uint32_t AMC::rand_new(uint64_t *next) { 00149 uint32_t temp; 00150 (*next) = (*next) * 1103515245 + 12345; 00151 temp = (*next) >> 16; 00152 return (temp % 32768); 00153 }; 00154 00155 void AMC::randb_thread_safe(int size, bvec &out, uint64_t *seed) { 00156 randb_thread_safe(0,size,out,seed); 00157 }; 00158 00159 00160 void AMC::randb_thread_safe(int start_ix, int length, bvec &out, uint64_t *seed) { 00161 for (int i1=start_ix;i1<start_ix+length;i1++) { 00162 out(i1)=rand_new(seed) & 1; 00163 }; 00164 }; 00165 00166 00167 void AMC::run_through_all_mcs(void) { 00168 #define NO_OF_FRAMES 1000 00169 00170 ivec modulation_orders="4,16,64,256"; 00171 00172 vec sigmas="1.5849 1.4125 1.2589 1.1220 1.0000 0.8913 \ 00173 0.7943 0.7079 0.6310 0.5623 0.5012 0.4467 \ 00174 0.3981 0.3548 0.3162 0.2818 0.2512 0.2239 \ 00175 0.1995 0.1778 0.1585 0.1413 0.1259 0.1122 \ 00176 0.1000 0.0891 0.0794 0.0708 0.0631 0.0562 \ 00177 0.0501 0.0447 0.0398 0.0355 0.0316 0.0282 "; 00178 00179 00180 int modulation_order; 00181 int l,r; 00182 double FER, BER, Rate, BERc, BERc_raw, BER_raw; 00183 mat results(modulation_orders.length()*no_of_codecs(),sigmas.length()); 00184 mat BERs(modulation_orders.length()*no_of_codecs(),sigmas.length()); 00185 mat BERs_raw(modulation_orders.length()*no_of_codecs(),sigmas.length()); 00186 00187 vec Rates(modulation_orders.length()*no_of_codecs()); 00188 bvec input, transmitted, message_hat, transmitted_hat; 00189 cvec symbols; 00190 00191 Real_Timer timer; 00192 double max_time=0; 00193 BERC berc; 00194 double s2; 00195 00196 input.set_size(codec_message_size(no_of_codecs()-1)); 00197 message_hat.set_size(codec_message_size(no_of_codecs()-1)); 00198 transmitted.set_size(m_code_word_size); 00199 transmitted_hat.set_size(m_code_word_size); 00200 symbols.set_size(m_code_word_size/log2((modulation_orders[0]))); 00201 RNG_reset(10); 00202 cout << "Hang on ... this is gonna take a while ...\n"; 00203 00204 for (int i1=0;i1<modulation_orders.length();i1++) { 00205 modulation_order=modulation_orders[i1]; 00206 cout << "Modulation order=" << modulation_order << endl; 00207 usleep(1000); 00208 00209 for (int c=0;c<no_of_codecs();c++) { 00210 cout << "Code number=" << c << endl; 00211 l=codec_message_size(c); 00212 00213 r=i1+c*modulation_orders.length(); 00214 Rate=(float (l))/((float) m_code_word_size)* 00215 log2((float) modulation_order); 00216 Rates(r)=Rate; 00217 max_time=0; 00218 00219 for (int i4=0;i4<sigmas.length();i4++) { 00220 FER=0; 00221 BERc=0; 00222 BERc_raw=0; 00223 usleep(10); 00224 00225 00226 for (uint32_t f=0;f<NO_OF_FRAMES;f++) { 00227 00228 input.set_subvector(0,randb(l)); 00229 modulate(modulation_order,c,input.mid(0,l),transmitted,symbols,0); 00230 usleep(10); 00231 00232 symbols=symbols+sigmas(i4)*randn_c(symbols.length()); 00233 timer.reset(); 00234 timer.start(); 00235 00236 s2=sigmas(i4)*sigmas(i4); 00237 s2=noise_variance(symbols.mid(0,m_code_word_size/log2( modulation_order)), modulation_order); 00238 00239 demodulate(symbols.mid(0, 00240 m_code_word_size/log2( modulation_order)), 00241 s2, 00242 modulation_order,c,message_hat,transmitted_hat); 00243 00244 timer.stop(); 00245 if (timer.get_time()>max_time) 00246 max_time=timer.get_time(); 00247 00248 berc.clear(); 00249 berc.count(transmitted,transmitted_hat); 00250 BER_raw=berc.get_errorrate(); 00251 00252 berc.clear(); 00253 berc.count(input.mid(0,l),message_hat.mid(0,l)); 00254 BER=berc.get_errorrate(); 00255 if (BER>0) 00256 FER=FER+(1.0/((double) NO_OF_FRAMES)); 00257 00258 BERc=BERc+(BER/((double) NO_OF_FRAMES)); 00259 BERc_raw=BERc_raw+(BER_raw/((double) NO_OF_FRAMES)); 00260 00261 00262 }; 00263 00264 std::cout << "res=" << i4 <<"," << s2 << "," << "FER=" << FER << std::endl; 00265 results(r,i4)=FER; 00266 BERs(r,i4)=BERc; 00267 BERs_raw(r,i4)=BERc_raw; 00268 }; 00269 std::cout << "Max used time=" << max_time << endl; 00270 }; 00271 }; 00272 00273 00274 it_file d1; 00275 d1.open("results_MCS.it"); 00276 d1<< Name("results") << results; 00277 d1<< Name("sigmas") << sigmas; 00278 d1<< Name("Rates") << Rates; 00279 d1<< Name("BERs") << BERs; 00280 d1<< Name("BERs_raw") << BERs_raw; 00281 d1.close(); 00282 00283 // Plot results in matlab 00284 // plot(-10*log10(sigmas),(1-results).*repmat(Rates,1,23),'-x') %Waterfall 00285 // plot(-10*log10(sigmas),results,'-x') % FER. 00286 00287 00288 };