StackedSpectrum.h

Go to the documentation of this file.
00001 #ifndef CSTACKEDSPECTRUM_H
00002 #define CSTACKEDSPECTRUM_H
00003 #include "TsSpectrum.h"
00004 #include "FatalException.h"
00005 #include <functional>
00006 #include <iterator>
00007 #include "statutils.h"
00008 #include <boost/bind.hpp>
00009 
00010 namespace gplib
00011   {
00012 
00013     /** \addtogroup tstools Time series analysis methods */
00014     /* @{ */
00015 
00016     //! This template is used to calculate stacked spectra for example for power spectrum estimation
00017     /*! The template StackedSpectrum calculates stacked spectra from an input time series. Two input iterators
00018      * define the input range, one output iterator the start of the output range, we have to provide the length
00019      * of individual segments and a windowing function. Make sure the container the output is stored in can hold at least seglength/2+1.
00020      * The Windowing function gets the relative position within the segment and should therefore be defined on the interval 0..1
00021      */
00022     template<typename InputIterator, typename OutputIterator,
00023         typename WindowFunctype>
00024     void StackedSpectrum(InputIterator tsbegin, InputIterator tsend,
00025         OutputIterator freqbegin, const size_t seglength, WindowFunctype WFunc)
00026       {
00027         //some convenience type definitions for the vectors that hold the input and output values
00028         typedef std::vector<
00029             typename std::iterator_traits<OutputIterator>::value_type>
00030             toutvector;
00031         typedef std::vector<
00032             typename std::iterator_traits<InputIterator>::value_type> tinvector;
00033         const size_t insize = distance(tsbegin, tsend);
00034         if (insize < seglength)
00035           throw FatalException(
00036               "Time Series shorter than requested segment length");
00037         const unsigned int nsegments = insize / seglength; //we do integer division, so the last (not full) segment will be discarded
00038         TsSpectrum SpecEst(false); //we do not want to perform multiple calculations
00039         std::fill_n(freqbegin, seglength / 2 + 1,
00040             typename std::iterator_traits<OutputIterator>::value_type()); // fill output with 0
00041         toutvector segspec(seglength / 2 + 1); //the spectrum of the current segment
00042 
00043         InputIterator currstart = tsbegin; //the start of the current segment
00044         InputIterator currend = tsbegin;
00045         advance(currend, seglength);
00046         for (unsigned int i = 0; i < nsegments; ++i)
00047           {
00048             tinvector currseg(currstart, currend); //temporary copy of time series
00049 
00050             SubMean(currseg.begin(), currseg.end());
00051 
00052             for (typename tinvector::iterator it = currseg.begin(); it
00053                 != currseg.end(); ++it)
00054               {
00055                 //multiply the current segment with the windowing function
00056                 *it *= WFunc(
00057                     static_cast<double> (distance(currseg.begin(), it))
00058                         / seglength); //by passing the relative position to the windowing function
00059               }
00060 
00061             //calculate the fourier transform for the current segment
00062             SpecEst.CalcSpectrum(currseg.begin(), currseg.end(),
00063                 segspec.begin(), segspec.end());
00064             //add the spectral values to the output vector
00065             std::transform(segspec.begin(), segspec.end(), freqbegin,
00066                 freqbegin, std::plus<typename std::iterator_traits<
00067                     OutputIterator>::value_type>());
00068             advance(currstart, seglength); //shift the boundaries of current segment
00069             advance(currend, seglength);
00070           }
00071       }
00072   /* @} */
00073   }
00074 #endif // CSTACKEDSPECTRUM_H

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