mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
psdVarMean.hpp
Go to the documentation of this file.
1 /** \file psdVarMean.hpp
2  * \brief Tools for calculating the variance of the mean of a PSD
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup signal_processing_files
7  *
8  */
9 
10 //***********************************************************************//
11 // Copyright 2018,2019,2020 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 psdVarMean_hpp
30 #define psdVarMean_hpp
31 
32 #include <vector>
33 
34 #include <gsl/gsl_integration.h>
35 #include <gsl/gsl_errno.h>
36 
37 #include "../math/func/bessel.hpp"
38 #include "../math/constants.hpp"
39 #include "../math/gslInterpolator.hpp"
40 
41 #include "psdFilter.hpp"
42 
43 namespace mx
44 {
45 namespace sigproc
46 {
47 
48 /// Parameters for calculating the variance of the mean from a numerical PSD.
49 /** Interpolates on the PSD for the integration.
50  *
51  * \tparam realT the real floating point type of the frequency and PSD vectors. [Must be double due to GSL]
52  */
53 template<typename _realT>
55 {
56  typedef _realT realT;
57 
58  std::vector<realT> * freq {nullptr}; ///< Pointer to the frequency vector
59  std::vector<realT> * psd {nullptr}; ///< Pointer to the psd vector
60  realT T {0}; ///< The sample length (units appropriate for freq)
61 
62  realT minf {0}; ///< The minimum frequency
63  realT maxf {0}; ///< The maximum frequency
64 
65  realT extrapAlpha{0};
66 
67  bool initialized {false}; ///< Flag controlling whether the interpolator is initialized
68 
69  #ifdef MX_OLD_GSL
71  #else
73  #endif
74 
75  /// Get the value of the PSD at k using interpolation
76  /** Extrapolates outside the range of frequencies in freq.
77  * Right now this is just constant.
78  *
79  * \todo implement better extrapolation past max-freq.
80  */
81  realT psdVal( realT k /**< [in] The transformed frequency coordinate */)
82  {
83  if( !initialized )
84  {
85  if(freq == nullptr || psd == nullptr)
86  {
87  std::cerr << "Vectors not set.\n";
88  exit(-1);
89  }
90  if(T == 0)
91  {
92  std::cerr << "T not set.\n";
93  exit(-1);
94  }
95 
96  terp.setup(*freq, *psd);
97  //#ifdef MX_OLD_GSL
98  //terp.setup(gsl_interp_linear, *freq, *psd);
99  //#else
100  //terp.setup(gsl_interp_steffen, *freq, *psd);
101  //#endif
102 
103  minf = (*freq)[0];
104  maxf = (*freq)[freq->size()-1];
105 
106  initialized = true;
107  }
108 
109  realT f = (2.0/T)*k;
110 
111  if(f < minf) return (*psd)[0];
112 
113  if(f > maxf)
114  {
115  //Enter extrapolation here
116  //return 0;//(*psd)[psd->size()-1];
117  if(extrapAlpha == 0) return 0;
118 
119  return (*psd)[psd->size()-1] * pow( f/maxf, -1*extrapAlpha);
120  }
121 
122  return terp(f);
123  }
124 };
125 
126 /// Integration worker function for psdVarMean::operator()
127 /**
128  * \tparam paramsT the type of the parameter structure. See psdVarMean.
129  *
130  * \returns the value of the integrand at k
131  *
132  *
133  */
134 template<typename paramsT>
135 typename paramsT::realT psdVarMeanFunc( typename paramsT::realT k, ///< [in] the scaled frequency coordinate
136  void * params ///< [in] pointer to the parameter structure
137  )
138 {
139  typedef typename paramsT::realT realT;
140 
141  paramsT * pvar = (paramsT *) params;
142 
143  realT J = math::func::bessel_j<realT, realT>(0.5, math::two_pi<realT>()*k);
144 
145  return J*J/k*pvar->psdVal(k);
146 
147 }
148 
149 /// Calculate the variance of the mean for a process given its PSD
150 /** Functor which manages the GSL integration workspace memory.
151  *
152  * \todo document the paramsT interface
153  *
154  * \tparam paramsT is a parameter structure with the correct interface.
155  *
156  * \ingroup psds
157  */
158 template<typename paramsT>
160 {
161  typedef typename paramsT::realT realT;
162 
163  realT extrapAlpha {0}; ///< The extrapolation exponent. No extrapolation if 0.
164 
165 protected:
166  gsl_integration_workspace * w {nullptr}; ///< The GSL integration workspace memory
167 
168  size_t wSize {10000}; ///< The size of the GSL workspace
169 
170  /// Initializes the gsl library.
171  void init()
172  {
173  ///\todo We'll get the occasional failure to reach tolerance error, just ignore them all for now.
174  gsl_set_error_handler_off();
175  }
176 
177 public:
178  /// Default c'tor
180  {
181  init();
182  }
183 
184  /// Constructor which initializes workspace size
185  psdVarMean( size_t wm /**< [in] Size of the GSL integration workspace*/)
186  {
187  init();
188  wSize = wm;
189  }
190 
191  /// d'tor cleans up the workspace memory
193  {
194  if(w != nullptr)
195  {
196  gsl_integration_workspace_free(w);
197  }
198  }
199 
200  /// Calculate the variance of the mean for a psd over a sample length
201  /**
202  * \returns the variance of the mean for the process governed by the PSD.
203  */
204  realT operator()( realT & error, ///< [out] The error estimate returned by gsl_integration_qagiu
205  std::vector<realT> & freq, ///< [in] The frequency vector
206  std::vector<realT> & psd, ///< [in] The psd vector
207  realT T ///< [in] The sample length (units approprate for freq)
208  )
209  {
210  if(w == nullptr)
211  {
212  w = gsl_integration_workspace_alloc(wSize);
213  }
214 
215  //Setup the integration parameters structure
216  paramsT pvar;
217 
218  pvar.freq = &freq;
219  pvar.psd = &psd;
220  pvar.T = T;
221 
222  pvar.extrapAlpha = extrapAlpha;
223 
224  //Setup the function
225  gsl_function func;
226 
227  func.function = &psdVarMeanFunc<paramsT>;
228  func.params = &pvar;
229 
230  realT result;
231 
232  int ec = gsl_integration_qagiu (&func, 0.0, 1e-14, 1e-8, wSize, w, &result, &error);
233  static_cast<void>(ec);
234 
235  return result/(2*T);
236  }
237 };
238 
239 
240 
241 } //namespace sigproc
242 } //namespace mx
243 
244 #endif //psdVarMean_hpp
Class to manage interpolation using the GSL interpolation library.
constexpr units::realT k()
Boltzmann Constant.
Definition: constants.hpp:71
The mxlib c++ namespace.
Definition: mxError.hpp:107
Declares and defines a class for filtering with PSDs.
paramsT::realT psdVarMeanFunc(typename paramsT::realT k, void *params)
Integration worker function for psdVarMean::operator()
Definition: psdVarMean.hpp:135
Parameters for calculating the variance of the mean from a numerical PSD.
Definition: psdVarMean.hpp:55
realT psdVal(realT k)
Get the value of the PSD at k using interpolation.
Definition: psdVarMean.hpp:81
realT minf
The minimum frequency.
Definition: psdVarMean.hpp:62
std::vector< realT > * freq
Pointer to the frequency vector.
Definition: psdVarMean.hpp:58
bool initialized
Flag controlling whether the interpolator is initialized.
Definition: psdVarMean.hpp:67
math::gslInterpolator< math::gsl_interp_linear< realT > > terp
Interpolator for the PSD.
Definition: psdVarMean.hpp:70
realT T
The sample length (units appropriate for freq)
Definition: psdVarMean.hpp:60
math::gslInterpolator< math::gsl_interp_steffen< realT > > terp
Interpolator for the PSD.
Definition: psdVarMean.hpp:72
realT maxf
The maximum frequency.
Definition: psdVarMean.hpp:63
std::vector< realT > * psd
Pointer to the psd vector.
Definition: psdVarMean.hpp:59
Calculate the variance of the mean for a process given its PSD.
Definition: psdVarMean.hpp:160
~psdVarMean()
d'tor cleans up the workspace memory
Definition: psdVarMean.hpp:192
gsl_integration_workspace * w
The GSL integration workspace memory.
Definition: psdVarMean.hpp:166
realT operator()(realT &error, std::vector< realT > &freq, std::vector< realT > &psd, realT T)
Calculate the variance of the mean for a psd over a sample length.
Definition: psdVarMean.hpp:204
realT extrapAlpha
The extrapolation exponent. No extrapolation if 0.
Definition: psdVarMean.hpp:163
size_t wSize
The size of the GSL workspace.
Definition: psdVarMean.hpp:168
psdVarMean()
Default c'tor.
Definition: psdVarMean.hpp:179
psdVarMean(size_t wm)
Constructor which initializes workspace size.
Definition: psdVarMean.hpp:185
void init()
Initializes the gsl library.
Definition: psdVarMean.hpp:171