WFunc.h

Go to the documentation of this file.
00001 #ifndef WFUNC_H_
00002 #define WFUNC_H_
00003 #include "types.h"
00004 #include <algorithm>
00005 #include <boost/bind.hpp>
00006 #include <boost/cast.hpp>
00007 #include <functional>
00008 
00009 namespace gplib
00010   {
00011 
00012     /** \addtogroup tstools Time series analysis methods */
00013     /* @{ */
00014 
00015     /*! \file WFunc.h
00016      *  This file defines several function objects to be used as windowing functions for spectral calculations
00017      * They all take one input parameter, the relative position in the time window, as a double between 0 and 1
00018      * and output the corresponding weighting factor. For efficiency reasons no checking is performed on the
00019      * input parameter. So make sure it is between 0 and 1, or you will get strange results. The easiest way
00020      * to apply the window function to some time series is to use the provided function ApplyWindow in this header file
00021      */
00022     //! This functor returns the weighting factor for the Hamming window, given the relative position relpos [0..1] in the time series
00023     struct Hamming: public std::unary_function<double, double>
00024       {
00025       double operator()(const double relpos)
00026         {
00027           return 0.54 - 0.46 * cos(2 * PI * relpos);
00028         }
00029       };
00030     //! This functor returns the weighting factor for the Hanning window, given the relative position (0..1) in the time series
00031     struct Hanning: public std::unary_function<double, double>
00032       {
00033       double operator()(const double relpos)
00034         {
00035           return 0.5 - 0.5 * cos(2 * PI * relpos);
00036         }
00037       };
00038     //! A functor for the simple Boxcar function
00039     struct Boxcar: public std::unary_function<double, double>
00040       {
00041       double operator()(const double relpos)
00042         {
00043           if (relpos >= 0.0 && relpos <= 1.0)
00044             return 1.0;
00045           else
00046             return 0.0;
00047         }
00048       };
00049 
00050     //! This functor rises steeply at the edges and then has a wide range where it is unity
00051     struct Steep: public std::unary_function<double, double>
00052       {
00053       double operator()(const double relpos)
00054         {
00055           const double startrange = 0.1;
00056           if (relpos < startrange)
00057             return 0.5 - 0.5 * cos(PI * relpos / startrange);
00058           else if (relpos > (1.0 - startrange))
00059             return 0.5 - 0.5 * cos(PI * ((1.0 - startrange) - relpos)
00060                 / startrange + PI);
00061           else
00062             return 1.0;
00063         }
00064       };
00065 
00066     //! The cosine squared windows of fixed width
00067     struct CosSq: public std::unary_function<double, double>
00068       {
00069       double operator()(const double relpos)
00070         {
00071           double val = cos(PI * relpos / 2);
00072           return val * val;
00073         }
00074       };
00075 
00076     //! A vraible width cosine squared window that is zero outside
00077     class TruncCosSq: public std::unary_function<double, double>
00078       {
00079     private:
00080       double width;
00081     public:
00082       TruncCosSq(double w = 1) :
00083         width(w)
00084         {
00085         }
00086       double operator()(const double relpos)
00087         {
00088           if (std::abs(relpos) > width)
00089             return 0.0;
00090 
00091           double val = cos(PI * relpos / (2 * width));
00092           return val * val;
00093         }
00094       };
00095 
00096     //! Apply one of the above window functions to a range
00097     /*!Apply one of the above window functions to a range
00098      * given by the iterators inbegin and outbegin and write the result into a structure through
00099      * the iterator outbegin, make sure the datastructure can hold enough elements. Input and output structures
00100      * can be the same.
00101      * */
00102     template<typename InputIterator, typename OutputIterator,
00103         typename WindowFunctype> inline
00104     void ApplyWindow(InputIterator inbegin, InputIterator inend,
00105         OutputIterator outbegin, WindowFunctype WFunc, double relshift = 0.0)
00106       {
00107         const double length = inend - inbegin;
00108         for (InputIterator it = inbegin; it != inend; ++it, ++outbegin)
00109           *outbegin = (*it) * WFunc(boost::numeric_cast<double>(distance(
00110               inbegin, it)) / length - relshift);
00111 
00112         //std::transform(inbegin,inend,outbegin,
00113         //      boost::bind(std::multiplies<typename std::iterator_traits<InputIterator>::value_type>(),_1,
00114         //              boost::bind(WFunc,boost::bind<double>(std::divides<typename std::iterator_traits<InputIterator>::value_type >(),_1,length))));
00115       }
00116   /* @} */
00117   }
00118 #endif /*WFUNC_H_*/

Generated on Tue May 4 16:52:15 2010 for GPLIB++ by  doxygen 1.5.8