spectrumsolver.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef spectrumsolverH
15 #define spectrumsolverH
16 //---------------------------------------------------------------------------
17 #include "support.h"
18 
19 #include <vector>
20 #include <complex>
21 #include <deque>
22 
23 #include <fft.h>
24 
25 //! Base class for spectrum solvers.
26 //! \sa FFTSolver, MEMStrict, CompositeSpectrumSolver, FreqEstimation, MemBurg, YuleWalkerAR
27 class DECLSPEC_KAME SpectrumSolver {
28 public:
30  virtual ~SpectrumSolver();
31 
32  //! Perform spectrum analysis.
33  void exec(const std::vector<std::complex<double> >& memin, std::vector<std::complex<double> >& memout,
34  int t0, double tol, FFT::twindowfunc windowfunc, double windowlength) throw (XKameError&);
35  const std::vector<std::complex<double> >& ifft() const {return m_ifft;}
36  //! \return (power, index) in descending order.
37  const std::vector<std::pair<double, double> >& peaks() const {return m_peaks;}
38 
39  typedef double (*tfuncIC)(double sigma2, int p, int t);
40 
41  //! Akachi's information criterion.
42  //! \param loglikelifood ln(L).
43  //! \param k # of parameters.
44  //! \param n # of samples.
45  static double icAIC(double loglikelifood, int k, int n);
46  //! Corrected Akachi's information criterion.
47  //! \sa icAIC
48  static double icAICc(double loglikelifood, int k, int n);
49  //! Hannan-Quinn information criterion.
50  //! \sa icAIC
51  static double icHQ(double loglikelifood, int k, int n);
52  //! Minimum Description Length.
53  //! \sa icAIC
54  static double icMDL(double loglikelifood, int k, int n);
55 
56  static double windowLength(int tdlen, int t0, double windowlength);
57 
58  //! Create a window waveform.
59  static void window(int t, int t0, FFT::twindowfunc windowfunc,
60  double windowlength, std::vector<double> &window);
61 
62  virtual bool isFT() const {return false;}
63 protected:
64  virtual void genSpectrum(const std::vector<std::complex<double> >& memin,
65  std::vector<std::complex<double> >& memout,
66  int t0, double tol, FFT::twindowfunc windowfunc, double windowlength) = 0;
67  std::vector<std::complex<double> > m_ifft;
68  std::vector<std::pair<double, double> > m_peaks;
69 
70  //! If false, perform rectangular windowing before solver process.
71  virtual bool hasWeighting() const {return false;}
72 
73  //! \return estimated number of effective (noisy) data points.
74  double numberOfNoises(const std::vector<std::complex<double> >& memin);
75 
76  void genIFFT(const std::vector<std::complex<double> >& wavein);
77  //! Least-square phase estimation.
78  //! \return coeff.
79  double lspe(const std::vector<std::complex<double> >& wavein, int origin,
80  const std::vector<double>& psd, std::vector<std::complex<double> >& waveout,
81  double tol, bool powfit, FFT::twindowfunc windowfunc);
82  //! \return err.
83  double stepLSPE(const std::vector<std::complex<double> >& wavein, int origin,
84  const std::vector<double>& psd, std::vector<std::complex<double> >& waveout,
85  bool powfit, double &coeff, const std::vector<double> &weight);
86 
87  shared_ptr<FFT> m_fftN, m_ifftN;
88  int fftlen() const {return m_ifftN->length();}
89 
90  //! For autocorrelation.
91  shared_ptr<FFT> m_fftRX, m_ifftRX;
92  void autoCorrelation(const std::vector<std::complex<double> >&wave,
93  std::vector<std::complex<double> >&corr);
94 };
95 
96 //! Zero-filled FFT spectrum solver.
97 class DECLSPEC_KAME FFTSolver : public SpectrumSolver {
98 public:
99  FFTSolver() : SpectrumSolver() {}
100  virtual ~FFTSolver() {}
101 protected:
102  virtual void genSpectrum(const std::vector<std::complex<double> >& memin,
103  std::vector<std::complex<double> >& memout,
104  int t0, double tol, FFT::twindowfunc windowfunc, double windowlength);
105  virtual bool hasWeighting() const {return true;}
106  virtual bool isFT() const {return true;}
107 };
108 
109 //! Extra-polation of data using MEM (Maximum Entropy Method) by assuming gaussian distribution.
110 class DECLSPEC_KAME MEMStrict : public SpectrumSolver {
111 public:
112  virtual ~MEMStrict();
113 protected:
114  virtual void genSpectrum(const std::vector<std::complex<double> >& memin,
115  std::vector<std::complex<double> >& memout,
116  int t0, double tol, FFT::twindowfunc windowfunc, double windowlength);
117 private:
118  void setup(unsigned int t, unsigned int n);
119  double stepMEM(const std::vector<std::complex<double> >& memin, std::vector<std::complex<double> >& memout,
120  double alpha, double sigma, int t0, double tol);
121  void solveZ(double tol);
122 
123  std::vector<std::complex<double> > m_lambda, m_accumDY, m_accumDYFT;
124  shared_ptr<FFT> m_fftT;
125  std::vector<double> m_accumG2;
126  double m_accumZ;
127 };
128 
129 //! Perform two spectrum solvers.
130 //! The preprocessor class \a T and postprocessor class \a X.
131 //! \a T is for an extra-polation of data and/or rejection of noises.
132 template <class T, class X>
133 class CompositeSpectrumSolver : public T {
134 public:
135 protected:
136  virtual void genSpectrum(const std::vector<std::complex<double> >& memin,
137  std::vector<std::complex<double> >& memout,
138  int t0, double tol, FFT::twindowfunc windowfunc, double windowlength) {
139  m_preprocessor.exec(memin, memout, t0, tol, windowfunc, windowlength);
140  int t = memin.size();
141  int n = memout.size();
142  int t0a = t0;
143  if(t0a < 0)
144  t0a += (-t0a / n + 1) * n;
145  std::vector<std::complex<double> > nsin(t);
146  for(int i = 0; i < t; i++) {
147  int j = (t0a + i) % n;
148  nsin[i] = m_preprocessor.ifft()[j];
149  }
150  T::genSpectrum(nsin, memout, t0, tol, windowfunc, windowlength);
151  }
152  X m_preprocessor;
153 };
154 
155 #endif

Generated for KAME4 by  doxygen 1.8.3