* Re: complex - direct access to members?
1999-01-31 23:58 ` Gabriel Dos Reis
@ 1999-01-31 23:58 ` nbecker
0 siblings, 0 replies; 11+ messages in thread
From: nbecker @ 1999-01-31 23:58 UTC (permalink / raw)
To: Gabriel Dos Reis; +Cc: egcs
[-- Attachment #1: Type: text/plain, Size: 492 bytes --]
>>>>> "Gabriel" == Gabriel Dos Reis <Gabriel.Dos-Reis@dptmaths.ens-cachan.fr> writes:
Gabriel> If you have any performance degradation due to the complex type as
Gabriel> currently implemented it would be helpfull if you could precise your
Gabriel> architecture, provide testcase and the optimization you use. Then, we
Gabriel> could see what we can do.
OK, here's an example.
I'm writing algorithms that interface via STL iterators. For example,
here is an FIR filter:
[-- Attachment #2: ComplexAdapt.H --]
[-- Type: text/x-c++, Size: 2392 bytes --]
#ifndef _ComplexAdapt_H
#define _ComplexAdapt_H
#include <complex>
#include <cstddef>
template<class T, class ComplexIterator>
class ComplexToRealAdapt {
private:
ComplexIterator I;
public:
typedef T value_type;
typedef ComplexToRealAdapt self;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
ComplexToRealAdapt (const ComplexIterator& C) :
I (C)
{}
value_type operator*() const {
return real (*I);
}
self& operator++ () {
I++;
return *this;
}
self operator++ (int) {
self tmp = *this;
++*this;
return tmp;
}
self& operator-- () {
I--;
return *this;
}
self operator-- (int) {
self tmp = *this;
--*this;
return tmp;
}
self& operator+=(difference_type n) {
I += n;
return *this;
}
self& operator-=(difference_type n) { return *this += -n; }
self operator+(difference_type n) const {
self tmp = *this;
return tmp += n;
}
value_type operator[](difference_type n) const { return *(*this + n); }
bool operator==(const self& x) const { return I == x.I; }
bool operator!=(const self& x) const { return !(*this == x); }
difference_type operator- (const self& x) const {
return I - x.I;
}
};
template<class T, class ComplexIterator>
class ComplexToImagAdapt {
private:
ComplexIterator I;
public:
typedef T value_type;
typedef ComplexToImagAdapt self;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
ComplexToImagAdapt (const ComplexIterator& C) :
I (C)
{}
value_type operator*() const {
return imag (*I);
}
self& operator++ () {
I++;
return *this;
}
self operator++ (int) {
self tmp = *this;
++*this;
return tmp;
}
self& operator-- () {
I--;
return *this;
}
self operator-- (int) {
self tmp = *this;
--*this;
return tmp;
}
self& operator+=(difference_type n) {
I += n;
return *this;
}
self& operator-=(difference_type n) { return *this += -n; }
self operator+(difference_type n) const {
self tmp = *this;
return tmp += n;
}
value_type operator[](difference_type n) const { return *(*this + n); }
bool operator==(const self& x) const { return I == x.I; }
bool operator!=(const self& x) const { return !(*this == x); }
difference_type operator- (const self& x) const {
return I - x.I;
}
};
#endif
[-- Attachment #3: QPSKDemod.H --]
[-- Type: text/x-c++, Size: 1279 bytes --]
#ifndef QPSKDemod_H
#define QPSKDemod_H
#include <complex>
#include "FIRRcvPulse.H"
#include "PulseShape.H"
#include "ComplexAdapt.H"
template<class T>
class QPSKDemod {
protected:
FIRRcvPulse<T> IrcvFP;
FIRRcvPulse<T> QrcvFP;
const int SPS;
const int decim;
public:
QPSKDemod (int _SPS, int _SI, const PulseShape<T>& _P, int _decim = 0);
template<class InputIterator, class OutputIterator>
void Compute (const InputIterator& instart, const InputIterator& inend, const OutputIterator& Iout, const OutputIterator& Qout);
};
template<class T>
QPSKDemod<T>::QPSKDemod (int _SPS, int _SI, const PulseShape<T>& _P, int _decim) :
IrcvFP (_P, _SPS, _SI, (_decim == 0) ? _SPS : _decim, 0),
QrcvFP (_P, _SPS, _SI, (_decim == 0) ? _SPS : _decim, 0),
SPS (_SPS),
decim (_decim)
{}
template<class T>
template<class InputIterator, class OutputIterator>
void QPSKDemod<T>::Compute (const InputIterator& instart, const InputIterator& inend, const OutputIterator& Iout, const OutputIterator& Qout) {
for (InputIterator in = instart; in != inend; in += decim) {
ComplexToRealAdapt<T, InputIterator> Rin (in);
ComplexToImagAdapt<T, InputIterator> Iin (in);
IrcvFP.Go (Rin+0, Rin+decim, Iout);
QrcvFP.Go (Iin+0, Iin+decim, Qout);
}
}
#endif
[-- Attachment #4: SimpleFIR.H --]
[-- Type: text/x-c++, Size: 9870 bytes --]
#ifndef _SimpleFIR_H
#define _SimpleFIR_H
#include <vector>
#include "RingBuffer.H"
// FIR assumes the buffering of the input is done externally.
template<class InputType, class OutputType = InputType, class CoefType = InputType> class FIRbase {
protected:
vector<CoefType> coef;
public:
template<class InputIterator>
FIRbase (InputIterator firsttap, InputIterator lasttap) :
coef (firsttap, lasttap) {}
FIRbase (const vector<CoefType>& _coef) :
coef (_coef) {}
const CoefType* Coef() const { return coef; }
int Len() const { return coef.size(); }
void Print (ostream& os) const;
};
template<class InputType, class OutputType = InputType, class CoefType = InputType> class FIR2base :
public FIRbase<InputType, OutputType, CoefType> {
protected:
RingBuffer<InputType> input;
template<class InputIterator>
void ShiftIn (const InputIterator& in);
template<class InputIterator>
void ShiftIn (const InputIterator& instart, const InputIterator& inend);
public:
template<class InputIterator>
FIR2base (InputIterator firsttap, InputIterator lasttap, int BufSize = lasttap - firsttap + 1) :
FIRbase<InputType, OutputType, CoefType> (firsttap, lasttap),
input (BufSize) {}
FIR2base (const vector<CoefType>& _coef, int BufSize = 0) :
FIRbase<InputType, OutputType, CoefType> (_coef),
input ((BufSize == 0) ? _coef.size() : BufSize)
{}
};
template<class InputType, class OutputType = InputType, class CoefType = InputType> class SimpleFIR :
public FIRbase<InputType, OutputType, CoefType> {
public:
template<class InputIterator>
SimpleFIR (InputIterator firsttap, InputIterator lasttap) :
FIRbase (firsttap, lasttap) {}
SimpleFIR (istream& is);
template<class InputIterator, class OutputIterator>
void Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff);
};
// FIR2 provides a ring buffer for the input internally
template<class InputType, class OutputType = InputType, class CoefType = InputType> class SimpleFIR2 :
public FIR2base<InputType, OutputType, CoefType> {
public:
template<class InputIterator>
SimpleFIR2 (InputIterator firsttap, InputIterator lasttap) :
FIR2base<InputType, OutputType, CoefType> (firsttap, lasttap) {}
SimpleFIR2 (istream& is);
template<class InputIterator, class OutputIterator>
void Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff);
OutputType Go (InputType in);
};
template<class InputType, class OutputType = InputType, class CoefType = InputType> class InterpFIR : public FIRbase<InputType, OutputType, CoefType> {
protected:
int interp;
public:
template<class InputIterator>
InterpFIR (InputIterator firsttap, InputIterator lasttap, int _interp) :
FIRbase (firsttap, lasttap),
interp (_interp)
{}
InterpFIR (vector<CoefType> V, int _interp) :
FIRbase (V),
interp (_interp)
{}
InterpFIR (istream& is, int _interp) :
FIRbase (V),
interp (_interp)
{}
template<class InputIterator, class OutputIterator>
void Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff);
};
template<class InputType, class OutputType = InputType, class CoefType = InputType> class InterpFIR2 :
public FIR2base<InputType, OutputType, CoefType> {
protected:
int interp;
public:
template<class InputIterator>
InterpFIR2 (InputIterator firsttap, InputIterator lasttap, int _interp) :
FIR2base<InputType, OutputType, CoefType> (firsttap, lasttap),
interp (_interp) {}
InterpFIR2 (istream& is, int _interp);
template<class InputIterator, class OutputIterator>
void Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff);
};
template<class InputType, class OutputType = InputType, class CoefType = InputType> class DecimFIR :
public FIRbase<InputType, OutputType, CoefType> {
protected:
int decim;
int phase;
public:
template<class InputIterator>
DecimFIR (InputIterator firsttap, InputIterator lasttap, int _decim, int _phase) :
FIRbase (firsttap, lasttap),
decim (_decim),
phase (_phase)
{}
DecimFIR (istream& is, int _decim, int _phase) :
FIRbase (V),
decim (_decim),
phase (_phase)
{}
template<class InputIterator, class OutputIterator>
void Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff);
};
template<class InputType, class OutputType = InputType, class CoefType = InputType>
class DecimFIR2 :
public FIR2base<InputType, OutputType, CoefType> {
private:
int decim;
int phase;
public:
template<class InputIterator>
DecimFIR2 (InputIterator firsttap, InputIterator lasttap, int _decim, int _phase, int BufSize = lasttap - firsttap + 1 + _decim) :
FIR2base<InputType, OutputType, CoefType> (firsttap, lasttap, BufSize),
decim (_decim),
phase (_phase) {}
DecimFIR2 (const vector<CoefType>& _coef, int _decim, int _phase, int BufSize = 0) :
FIR2base<InputType, OutputType, CoefType> (_coef, (BufSize == 0) ? _coef.size() + _decim : BufSize),
decim (_decim),
phase (_phase)
{}
// DecimFIR2 (istream& is, int _decim, int _phase);
int Decim() const { return decim; }
template<class InputIterator, class OutputIterator>
void Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff);
};
template<class InputType, class OutputType, class CoefType>
SimpleFIR<InputType, OutputType, CoefType>::SimpleFIR (istream& is)
{
while (is) {
CoefType x;
is >> x;
if (is)
coef->push_back (x);
}
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator, class OutputIterator>
void SimpleFIR<InputType, OutputType, CoefType>::Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outstart) {
OutputIterator O = outstart;
for (InputIterator in = instart; in != inend; in++) {
OutputType sum = 0;
for (int s = 0; s < Len(); s++)
sum += coef[s] * in[-s];
*O++ = sum;
}
}
#include <iostream.h>
template <class InputType, class OutputType, class CoefType>
void FIRbase<InputType, OutputType, CoefType>::Print( ostream& os ) const {
for( int i = 0; i < coef.size(); i++ )
os << i << '\t' << coef[ i ] << endl;
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator>
void FIR2base<InputType, OutputType, CoefType>::ShiftIn (const InputIterator& in) {
input.Shift ();
input[0] = in[0];
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator>
void FIR2base<InputType, OutputType, CoefType>::ShiftIn (const InputIterator& instart, const InputIterator& inend) {
for (InputIterator in = instart; in != inend; in++) {
input.Shift ();
input[0] = *in;
}
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator, class OutputIterator>
void SimpleFIR2<InputType, OutputType, CoefType>::Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff) {
OutputIterator O = outbuff;
for (InputIterator in = instart; in != inend; in++) {
ShiftIn (in);
OutputType sum = 0;
for (int s = 0; s < Len(); s++)
sum += coef[s] * input[-s];
*O++ = sum;
}
}
template<class InputType, class OutputType, class CoefType>
OutputType SimpleFIR2<InputType, OutputType, CoefType>::Go (InputType in) {
ShiftIn (&in);
OutputType sum = 0;
for (int s = 0; s < Len(); s++)
sum += coef[s] * input[-s];
return sum;
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator, class OutputIterator>
void InterpFIR<InputType, OutputType, CoefType>::Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff) {
OutputIterator O = outbuff;
for (InputIterator in = instart; in != inend; in++) {
for (int phase = 0; phase < interp; phase++) {
OutputType sum = 0;
// for (int i = 0; i < Len(); i++)
int i = 0;
while ((i * interp) + phase < Len()) {
sum += coef[(i * interp) + phase] * in[-i];
i++;
}
*O++ = sum;
}
}
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator, class OutputIterator>
void InterpFIR2<InputType, OutputType, CoefType>::Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff) {
for (InputIterator in = instart; in != inend; in++) {
ShiftIn (in);
OutputIterator O = outbuff;
for (int phase = 0; phase < interp; phase++) {
OutputType sum = 0;
int i = 0;
while ((i * interp) + phase < Len()) {
sum += coef[(i * interp) + phase] * input[-i];
i++;
}
*O++ = sum;
}
}
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator, class OutputIterator>
void DecimFIR<InputType, OutputType, CoefType>::Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff) {
OutputIterator O = outbuff;
for (InputIterator in = instart; in != inend; in += decim) {
OutputType sum = 0;
for (int i = 0; i < Len(); i++)
sum += coef[i] * in[-(i+phase)];
*O++ = sum;
}
}
template<class InputType, class OutputType, class CoefType>
template<class InputIterator, class OutputIterator>
void DecimFIR2<InputType, OutputType, CoefType>::Go (const InputIterator& instart, const InputIterator& inend, const OutputIterator& outbuff) {
OutputIterator O = outbuff;
for (InputIterator in = instart; in != inend; in += decim) {
ShiftIn (in, in+decim);
OutputType sum = 0;
for (int i = 0; i < Len(); i++)
sum += coef[i] * input[-(i+phase)];
*O++ = sum;
}
}
#endif
^ permalink raw reply [flat|nested] 11+ messages in thread