/*! \file Tabulated Function for complex numbers which are internally stored with log10(amplitude) and phase. This allows retention of phases bigger than 2*pi, which is important both for interpolation and operations like pow(). A nicer solution would actually be a templated TabulatedFunction class. \author T. Huege \version $Id$ \date 10 Jun 2009 */ #ifndef _utl_TabulatedFunctionComplexLgAmpPhase_h_ #define _utl_TabulatedFunctionComplexLgAmpPhase_h_ #include #include #include #include #include namespace utl { /*! \class TabulatedFunctionComplexLgAmpPhase TabulatedFunctionComplexLgAmpPhase.h "utl/TabulatedFunctionComplexLgAmpPhase.h" \author Luis Prado Jr. et al. \brief Class to hold collection (x,y) points and provide interpolation between them, where y are complex numbers. Tabulated Function for complex numbers which are internally stored with log10(amplitude) and phase. This allows retention of phases bigger than 2*pi, which is important both for interpolation and operations like pow(). A nicer solution would actually be a templated TabulatedFunction class. \version $Id$ \date 10 Jun 2009 \ingroup math */ class TabulatedFunctionComplexLgAmpPhase { public: typedef std::vector Array; typedef std::vector ArrayComplex; typedef TabulatedFunctionComplexLgAmpPhaseIterator Iterator; typedef ConstTabulatedFunctionComplexLgAmpPhaseIterator ConstIterator; TabulatedFunctionComplexLgAmpPhase(const double boundaryTolerance = 1e-3) : fBoundaryTolerance(boundaryTolerance) { } TabulatedFunctionComplexLgAmpPhase(const std::vector& xValues, const std::vector& yValues, const double boundaryTolerance = 1e-3) : fBoundaryTolerance(boundaryTolerance) { FillTable(xValues, yValues); } virtual ~TabulatedFunctionComplexLgAmpPhase() { } unsigned int GetNPoints() const { return fX.size(); } /// Note: cannot be used in assignment PairComplexLgAmpPhase operator[](const int idx) const { return PairComplexLgAmpPhase(fX[idx], fY[idx]); } void Clear() { fX.clear(); fY.clear(); } void PushBack(const double x, const utl::ComplexLgAmpPhase& y); Iterator Begin() { return Iterator(fX.begin(), fY.begin()); } Iterator End() { return Iterator(fX.end(), fY.end()); } ConstIterator Begin() const { return ConstIterator(fX.begin(), fY.begin()); } ConstIterator End() const { return ConstIterator(fX.end(), fY.end()); } /// begin of array of X Array::iterator XBegin() { return fX.begin(); } /// begin of array of X Array::const_iterator XBegin() const { return fX.begin(); } /// begin of array of Y ArrayComplex::iterator YBegin() { return fY.begin(); } /// begin of array of Y ArrayComplex::const_iterator YBegin() const { return fY.begin(); } /// end of array of X Array::iterator XEnd() { return fX.end(); } /// end of array of X Array::const_iterator XEnd() const { return fX.end(); } /// end of array of Y ArrayComplex::iterator YEnd() { return fY.end(); } /// end of array of Y ArrayComplex::const_iterator YEnd() const { return fY.end(); } /// read-only reference to front of array of X Array::const_reference XFront() const { return fX.front(); } /// read-only reference to front of array of Y ArrayComplex::const_reference YFront() const { return fY.front(); } /// read-only reference to back of array of X Array::const_reference XBack() const { return fX.back(); } /// read-only reference to back of array of Y ArrayComplex::const_reference YBack() const { return fY.back(); } Iterator Insert(const double x, const utl::ComplexLgAmpPhase& y); //ConstIterator Find(const double x, const double y) const; ConstIterator FindX(const double x) const; ConstIterator FindY(const utl::ComplexLgAmpPhase& y) const; /// Get or interpolate the Y value that corresponds to parameter \p x utl::ComplexLgAmpPhase Y(const double x) const; /// Interpolate the Y value with a \p polyDegree polynomial //utl::ComplexLgAmpPhase InterpolateY(const double x, const int polyDegree) const; // get/set the \p idx-th value of the Ys const utl::ComplexLgAmpPhase& GetY(const unsigned int idx) const { return fY[idx]; } // get/set the \p idx-th value of the Xs const double& GetX(const unsigned int idx) const { return fX[idx]; } double& GetX(const unsigned int idx) { return fX[idx]; } utl::ComplexLgAmpPhase& GetY(const unsigned int idx) { return fY[idx]; } /// return the sum of X values double SumX() const { return std::accumulate(fX.begin(), fX.end(), 0.); } bool IsInValidRange(const double x) const; bool operator==(const TabulatedFunctionComplexLgAmpPhase& t) const { return fX == t.fX && fY == t.fY; } bool operator!=(const TabulatedFunctionComplexLgAmpPhase& t) const { return !operator==(t); } double GetBoundaryTolerance() const { return fBoundaryTolerance; } void SetBoundaryTolerance(const double tolerance) { fBoundaryTolerance = tolerance; } //TabulatedFunctionComplexLgAmpPhase operator*(const TabulatedFunctionComplexLgAmpPhase& rhs) const; /// multiply the current TabulatedFunctionComplexLgAmpPhase with another one TabulatedFunctionComplexLgAmpPhase& operator*=(const TabulatedFunctionComplexLgAmpPhase& rhs); /// calculate the power of a TabulatedFunctionComplexLgAmpPhase (correctly treating amplitude and phase) void Pow(const double power); protected: void FillTable(const std::vector& xValues, const std::vector& yValues); double fBoundaryTolerance; Array fX; ArrayComplex fY; }; } #endif // Configure (x)emacs for this file ... // Local Variables: // mode: c++ // compile-command: "make -C .. -k" // End: