mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
autocorrelation.hpp
Go to the documentation of this file.
1 /** \file autocorrelation.hpp
2  * \brief Tools for working with autocorrelations
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup signal_processing_files
7  *
8  */
9 
10 //***********************************************************************//
11 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
12 //
13 // This file is part of mxlib.
14 //
15 // mxlib is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // mxlib is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
27 //***********************************************************************//
28 
29 #ifndef autocorrelation_hpp
30 #define autocorrelation_hpp
31 
32 #include "../math/fft/fft.hpp"
33 
34 namespace mx
35 {
36 
37 namespace sigproc
38 {
39 
40 
41 ///Calculate the autocorrelation of a time-series
42 /**
43  * \tparam T is the real type of the data and autocorrelation.
44  *
45  * \ingroup signal_processing
46  */
47 template<typename T>
48 void autocorrelation( T * ac, ///< [out] is the pre-allocated array of length Nac which will contain the autocorrelation on return
49  size_t Nac, ///< [in] is the length of ac
50  T * sig, ///< [in] is the input time-series (signal)
51  size_t Nsig ///< [in] is the length of the input time-series
52  )
53 {
54 
55  #pragma omp parallel for
56  for(int i=0; i< Nac; ++i)
57  {
58  ac[i] = 0;
59 
60  for(int j=0; j<Nsig-i; ++j)
61  {
62  ac[i] += sig[j]*sig[j+i];
63  }
64  }
65 
66  T norm = ac[0];
67  for(int i=0; i<Nac; ++i) ac[i] /= norm;
68 }
69 
70 ///Calculate the autocorrelation of a time-series
71 /**
72  * \tparam T is the real type of the data and autocorrelation.
73  *
74  * \todo this should probably re-allocate if ac.size() != sig.size(), or at least <
75  *
76  * \ingroup signal_processing
77  */
78 template<typename T>
79 void autocorrelation( std::vector<T> & ac, ///< [out] will contain the autocorrelation on return. If ac.size()==0 then it is resized to sig.size().
80  std::vector<T> & sig ///< [in] is the input time-series (signal)
81  )
82 {
83  if(ac.size()==0) ac.resize(sig.size());
84  autocorrelation( ac.data(), ac.size(), sig.data(), sig.size());
85 }
86 
87 /// Functor for calculating the autocorrelation given a PSD
88 /** Stores the fftT object and related working memory so that
89  * repeated calls do not re-allocate or re-plan the FFT.
90  *
91  * \tparam T is the real type of the PSD and resultig A.C.
92  *
93  * \ingroup signal_processing
94  */
95 template<typename T>
97 {
98  std::vector<std::complex<T>> fftOut;
99  std::vector<std::complex<T>> fftIn;
100 
101  math::fft::fftT<std::complex<T>, std::complex<T>, 1, 0> fft;
102 
103  /// Calculate the A.C. as the inverse FFT of the PSD
104  /** This calculates the circular autocorrelation from the PSD.
105  *
106  */
107  void operator()( T * ac, ///< [out] pre-allocated array, on output contains the first Nac points of the autocorrelation
108  size_t Nac, ///< [in] the allocated size of ac.
109  T * psd, ///< [in] the 2-sided FFT storage order PSD
110  size_t Npsd ///< [in] the number of points in the PSD
111  )
112  {
113  fft.plan( Npsd, MXFFT_FORWARD);
114 
115  fftOut.resize(Npsd);
116  fftIn.resize(Npsd);
117 
118  for(size_t i=0; i< Npsd; ++i) fftIn[i] = psd[i];
119 
120  fft( fftOut.data(),fftIn.data() );
121 
122  T norm = fftOut[0].real();
123  for(size_t i=0; i < Npsd && i < Nac; ++i) ac[i] = fftOut[i].real()/norm;
124 
125  }
126 
127  /// Calculate the A.C. as the inverse FFT of the PSD
128  /** This calculates the circular autocorrelation from the PSD.
129  *
130  */
131  void operator() ( std::vector<T> & ac, ///< [out] On output contains the autocorrelation. If ac.size()==0, it is allocated to psd.size().
132  std::vector<T> & psd ///< [in] the 2-sided FFT storage order PSD
133  )
134  {
135  if(ac.size() == 0) ac.resize(psd.size());
136  operator()( ac.data(), ac.size(), psd.data(), psd.size() );
137  }
138 };
139 
140 
141 
142 } //namespace sigproc
143 } //namespace mx
144 
145 #endif //autocorrelation_hpp
void autocorrelation(std::vector< T > &ac, std::vector< T > &sig)
Calculate the autocorrelation of a time-series.
The mxlib c++ namespace.
Definition: mxError.hpp:107
Functor for calculating the autocorrelation given a PSD.
void operator()(T *ac, size_t Nac, T *psd, size_t Npsd)
Calculate the A.C. as the inverse FFT of the PSD.