00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef BSE
00022 #define BSE
00023
00024 #include <math.h>
00025 #include <complex.h>
00026 #include <delay.h>
00027 #include <fir_adapt.h>
00028 namespace SPUC {
00032
00033
00034
00042 template <class Numeric> class mle
00043 {
00044 public:
00045 const long mlsd_span;
00046 const long dfe_span;
00047 long n_branches;
00048 long n_states;
00049 Numeric fb_est;
00050 fir_adapt< Numeric > cfir;
00051 Numeric* cir_mlsd;
00052 Numeric* cir_dfe;
00053 Numeric* f_est;
00054 Numeric* b_est;
00055 double* weight;
00056 long* path;
00057 long* tmp_path;
00058 double* tmp_weight;
00059 long* path_symbol;
00060 long phase_states;
00061 long total_states;
00062 double phase_inc;
00063
00066 mle(int mlsd_size, int dfe_size=0, long q=1) :
00067 mlsd_span(mlsd_size+1),
00068 dfe_span(dfe_size)
00069 {
00070 n_states = (1 << (q*mlsd_size));
00071 n_branches = (2*q*n_states);
00072 cfir.set_size(mlsd_span);
00073 cir_mlsd = new Numeric[mlsd_span];
00074 cir_dfe = new Numeric[dfe_span];
00075 f_est = new Numeric[n_branches];
00076 b_est = new Numeric[n_states];
00077 weight = new double[n_states];
00078 path = new long[n_states];
00079 tmp_path = new long[n_states];
00080 tmp_weight = new double[n_states];
00081 path_symbol = new long[n_states];
00082 for (int i=0;i<n_states;i++) {
00083 path_symbol[i] = 0;
00084 path[i] = 0;
00085 weight[i] = 0;
00086 }
00087 fb_est = 0;
00088 }
00089 ~mle(void) {
00090 delete [] path;
00091 delete [] path_symbol;
00092 delete [] weight;
00093 }
00095 void reset() { cfir.reset(); }
00097 void update_taps_lms(Numeric err) {
00098 cfir.update_lms(err);
00099 }
00101 Numeric tap0(void) { return(cfir.coeff[0]); }
00103 void set_cir(const fir < Numeric >& cir) {
00104 int i;
00105 for (i=0;i<mlsd_span;i++) cir_mlsd[i] = cir.coeff[i];
00106 for (i=0;i<dfe_span;i++) {
00107 if (i+mlsd_span < cir.num_taps)
00108 cir_dfe[i] = cir.coeff[mlsd_span+i];
00109 else
00110 cir_dfe[i] = 0;
00111 }
00112 }
00115 Numeric df_est(int state) {
00116 int pnt,i;
00117 Numeric est = 0.0;
00118 pnt = 0x1;
00119 for (i=0;i<dfe_span;i++) {
00120 if ((path[state] & pnt) != 0) est += cir_dfe[i];
00121 else est -= cir_dfe[i];
00122 pnt <<= 1;
00123 }
00124 return(est);
00125 }
00127 Numeric ff_estimate(long seq) {
00128 int j, i;
00129 long num_taps = mlsd_span;
00130 Numeric pred = 0;
00131 j = (0x1 << num_taps);
00132 for(i = 0; i < num_taps; i++) {
00133 j >>= 1;
00134 if((seq & j) != 0) pred += cfir.coeff[i];
00135 else pred -= cfir.coeff[i];
00136 }
00137 return(pred);
00138 }
00140 double estimate(Numeric rx, long seq, long state, long type) {
00141 Numeric y;
00142 if (type == 1) {
00143 y = ff_estimate(seq)+ fb_est;
00144 return(magsq(y-rx));
00145 } else if (type == 2) {
00146 y = ff_estimate(seq)+ b_est[state];
00147 return(magsq(y-rx));
00148 } else {
00149 y = ff_estimate(seq);
00150 return(magsq(y-rx));
00151 }
00152
00153 }
00155 long ddfse(Numeric rx) {return(equalize(rx, 2));}
00157 long mlsd(Numeric rx) {return(equalize(rx, 0));}
00159 long rsdfse(Numeric rx){return(equalize(rx,1));}
00161 long equalize(Numeric rx, long type) {
00162 double temp0,temp1;
00163 long ex_state0, ex_state1;
00164 long old_state0, old_state1;
00165 double metric0,metric1;
00166 double min_weight;
00167 long path_state;
00168 int i;
00169 for (i=0;i<n_states;i++) {
00170
00171 ex_state0 = (i<<1);
00172
00173 metric0 = estimate(rx, ex_state0, i, type);
00174 old_state0 = ex_state0 % n_states;
00175 temp0 = weight[old_state0] + metric0;
00176
00177 ex_state1 = ex_state0 + 1;
00178
00179 metric1 = estimate(rx, ex_state1, i+n_states, type);
00180 old_state1 = ex_state1 % n_states;
00181 temp1 = weight[old_state1] + metric1;
00182 if (temp0 < temp1) {
00183 tmp_weight[i] = temp0;
00184 tmp_path[i] = (path[old_state0] << 1);
00185 } else {
00186 tmp_weight[i] = temp1;
00187 tmp_path[i] = (path[old_state1] << 1) | 0x1;
00188 }
00189 }
00190
00191
00192
00193
00194
00195 min_weight = tmp_weight[0];
00196 path_state = 0;
00197 for (i=0;i<n_states;i++) {
00198 if (tmp_weight[i] < min_weight) {
00199 min_weight = tmp_weight[i];
00200 path_state = i;
00201 }
00202
00203 weight[i] = tmp_weight[i];
00204 path[i] = tmp_path[i];
00205 b_est[i] = df_est(i);
00206 fb_est = df_est(path_state);
00207 }
00208 return(path[path_state]);
00209 }
00210 };
00211 }
00212 #endif