- initial version
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/cpp@90 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
@@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
* File: Equalizer.hpp
|
||||||
|
* Author: jens
|
||||||
|
*
|
||||||
|
* Created on 20. Dezember 2014, 09:24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQUALIZER_HPP
|
||||||
|
#define EQUALIZER_HPP
|
||||||
|
|
||||||
|
#include "Vector.hpp"
|
||||||
|
#include "FirComplex.hpp"
|
||||||
|
|
||||||
|
namespace Radio
|
||||||
|
{
|
||||||
|
namespace Equalizer
|
||||||
|
{
|
||||||
|
|
||||||
|
class AEqualizer : public FirComplex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AEqualizer(uint32_t numTaps)
|
||||||
|
: FirComplex(numTaps)
|
||||||
|
, m_w(numTaps)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AEqualizer() {}
|
||||||
|
|
||||||
|
void setNumTaps(uint32_t numTaps)
|
||||||
|
{
|
||||||
|
FirComplex::setNumTaps(numTaps);
|
||||||
|
m_w.resize(numTaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUnit(uint32_t delay)
|
||||||
|
{
|
||||||
|
m_w.setZero();
|
||||||
|
m_w(delay) = ComplexScalar(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CVec& getWeights()
|
||||||
|
{
|
||||||
|
return m_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AEqualizer& operator=(const AEqualizer &rhs)
|
||||||
|
{
|
||||||
|
this->m_w = rhs.m_w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CVec m_w;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lms : public AEqualizer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Lms(uint32_t numTaps)
|
||||||
|
: AEqualizer(numTaps)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
~Lms()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(ComplexScalar const &e, RealScalar const &mu)
|
||||||
|
{
|
||||||
|
m_w += m_x * conj(e) * mu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class Cma : public Lms
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Cma(uint32_t numTaps=0)
|
||||||
|
: Lms(numTaps)
|
||||||
|
, m_xLast(0)
|
||||||
|
, m_power(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(uint32_t numTaps)
|
||||||
|
{
|
||||||
|
setNumTaps(numTaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexScalar process(ComplexScalar const &x)
|
||||||
|
{
|
||||||
|
RealScalar x1, x2;
|
||||||
|
|
||||||
|
x1 = abs(x);
|
||||||
|
x2 = abs(m_x[m_numTaps-1]);
|
||||||
|
m_power = max(RealScalar(0), m_power + (x1*x1 - m_xLast));
|
||||||
|
m_xLast = x2*x2;
|
||||||
|
|
||||||
|
FirComplex::feed(x);
|
||||||
|
return FirComplex::process(m_w);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proakis: page 698
|
||||||
|
void trainGodard(ComplexScalar const &sym_s_eq, RealScalar const &mag_h, RealScalar R2, RealScalar mu)
|
||||||
|
{
|
||||||
|
ComplexScalar d;
|
||||||
|
ComplexScalar e;
|
||||||
|
RealScalar mag_s, t;
|
||||||
|
|
||||||
|
mag_s = abs(sym_s_eq);
|
||||||
|
|
||||||
|
t = (RealScalar)((mag_h + R2*mag_s - mag_s*mag_s*mag_s)/(1E-4+mag_h));
|
||||||
|
d = sym_s_eq * t;
|
||||||
|
|
||||||
|
e = d - sym_s_eq;
|
||||||
|
mu /= (1+m_power);
|
||||||
|
|
||||||
|
Lms::update(e, mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Sliced Multi-modulus Blind Equalization Algorithm",
|
||||||
|
// ETRI Journal, Volume 27, Number 3, June 2005,
|
||||||
|
// Shafayat Abrar and Roy A. Axford Jr.
|
||||||
|
void trainMma(ComplexScalar const &sym_s_eq, ComplexScalar const &R, RealScalar mu)
|
||||||
|
{
|
||||||
|
ComplexScalar e(sym_s_eq.real()*(R.real() - sym_s_eq.real()*sym_s_eq.real()), sym_s_eq.imag()*(R.imag() - sym_s_eq.imag()*sym_s_eq.imag()));
|
||||||
|
|
||||||
|
mu /= (1+m_power);
|
||||||
|
Lms::update(e, mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Sliced Multi-modulus Blind Equalization Algorithm",
|
||||||
|
// ETRI Journal, Volume 27, Number 3, June 2005,
|
||||||
|
// Shafayat Abrar and Roy A. Axford Jr.
|
||||||
|
void trainSmma(ComplexScalar const &sym_s_eq, RealScalar const &mag_h, ComplexScalar const &R, RealScalar mu)
|
||||||
|
{
|
||||||
|
ComplexScalar e(sym_s_eq.real()*(mag_h*R.real() - sym_s_eq.real()*sym_s_eq.real()), sym_s_eq.imag()*(mag_h*R.imag() - sym_s_eq.imag()*sym_s_eq.imag()));
|
||||||
|
|
||||||
|
mu /= (1+m_power);
|
||||||
|
Lms::update(e, mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RealScalar m_xLast;
|
||||||
|
RealScalar m_power;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Dfe : public Lms
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dfe(uint32_t k=0)
|
||||||
|
: Lms(2*k+1)
|
||||||
|
, m_numFeedforward(k+1)
|
||||||
|
, m_numFeedBack(k)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~Dfe()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void init(uint32_t k)
|
||||||
|
{
|
||||||
|
setNumTaps(2*k+1);
|
||||||
|
m_numFeedforward = k+1;
|
||||||
|
m_numFeedBack = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexScalar process(ComplexScalar const &xs, ComplexScalar const &xh)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
CVec &x = m_x;
|
||||||
|
|
||||||
|
// x(0:size-1) = [xs, x(0:m_numFeedforward-2), xh, x(m_numFeedforward:size-2)]
|
||||||
|
m_x.reverse() << m_x.segment(m_numFeedforward-1, m_numFeedBack).reverse(),xh,m_x.segment(0, m_numFeedforward-2).reverse(),xs;
|
||||||
|
|
||||||
|
return FirComplex::process(m_w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void train(ComplexScalar e, RealScalar mu)
|
||||||
|
{
|
||||||
|
Lms::update(e, mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_numFeedforward;
|
||||||
|
uint32_t m_numFeedBack;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // Radio::Equalizer
|
||||||
|
} // ::Radio
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* EQUALIZER_HPP */
|
||||||
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* File: FirComplex.hpp
|
||||||
|
* Author: jens
|
||||||
|
*
|
||||||
|
* Created on 20. Dezember 2014, 08:12
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FIRCOMPLEX_HPP
|
||||||
|
#define FIRCOMPLEX_HPP
|
||||||
|
|
||||||
|
#include "Vector.hpp"
|
||||||
|
|
||||||
|
namespace Radio
|
||||||
|
{
|
||||||
|
|
||||||
|
class FirComplex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FirComplex(uint32_t numTaps = 0)
|
||||||
|
: m_numTaps(numTaps)
|
||||||
|
, m_x(numTaps)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~FirComplex()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNumTaps(uint32_t numTaps)
|
||||||
|
{
|
||||||
|
m_numTaps = numTaps;
|
||||||
|
m_x.resize(numTaps);
|
||||||
|
// m_x.fill(ComplexScalar(0,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void feed(ComplexScalar const &x)
|
||||||
|
{
|
||||||
|
// m_x.reverse().head(m_numTaps-1) = m_x.reverse().tail(m_numTaps-1);
|
||||||
|
|
||||||
|
m_x.reverse() << m_x.head(m_numTaps-1).reverse(), x;
|
||||||
|
// m_x(0) = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexScalar process(CVec const &coeff)
|
||||||
|
{
|
||||||
|
return m_x.transpose() * coeff.conjugate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint32_t m_numTaps;
|
||||||
|
CVec m_x;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // ::Radio
|
||||||
|
|
||||||
|
#endif /* FIRCOMPLEX_HPP */
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
include ../config.mk
|
||||||
|
|
||||||
|
SRCDIR := .
|
||||||
|
OBJS := real.o cpx.o ringbuf.o equalizer.o interpolation.o agc.o nco.o statistics.o symbol.o synchronization.o Frame.o
|
||||||
|
|
||||||
|
LIB := $(BUILD_DIR)/libradio.a
|
||||||
|
|
||||||
|
INCLUDES := . ..
|
||||||
|
DEFINES := radio_float_t=float fir_float_t=float
|
||||||
|
|
||||||
|
all : $(LIB)
|
||||||
|
|
||||||
|
$(LIB) : $(OBJS)
|
||||||
|
$(AR) -r $(LIB) $(OBJS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
rm -f *.a
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
include ../compile.mk
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* File: Vector.hpp
|
||||||
|
* Author: jens
|
||||||
|
*
|
||||||
|
* Created on 19. Dezember 2014, 18:24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VECTOR_HPP
|
||||||
|
#define VECTOR_HPP
|
||||||
|
|
||||||
|
#include <Eigen/Dense>
|
||||||
|
#include "../radio/radio_types.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace Eigen;
|
||||||
|
|
||||||
|
#ifndef radio_float_t
|
||||||
|
#define radio_float_t float
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Radio
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef radio_float_t RealScalar;
|
||||||
|
typedef complex<radio_float_t> ComplexScalar;
|
||||||
|
|
||||||
|
typedef Matrix<RealScalar, Dynamic, 1> RVec;
|
||||||
|
typedef Matrix<ComplexScalar, Dynamic, 1> CVec;
|
||||||
|
|
||||||
|
static ComplexScalar toComplexScalar(cpx_t v)
|
||||||
|
{
|
||||||
|
return ComplexScalar(v.real, v.imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cpx_t toCpx(ComplexScalar v)
|
||||||
|
{
|
||||||
|
return Cpx(v.real(), v.imag());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // ::Radio
|
||||||
|
|
||||||
|
#endif /* VECTOR_HPP */
|
||||||
|
|
||||||
Reference in New Issue
Block a user