非均匀取样数据的功率谱估计方法
一般来说,对均匀间隔采样的数据的功率谱估计,可以采用DFT/AR/MA/ARMA/MUSIC等方法估计;
如果由于实验条件限制,或者偶尔的数据丢失,采样的数据间隔时间/空间不是均匀间隔的,此时,大致可以有两种处理方式:
1)用插值的方法将数据转换为等间隔的,然后按等间隔采样方法处理;这种方法最大的缺陷是,在低频成分处会出现假的凸起。
2)采用Lomb方法处理;
本文将给出Lomb方法公式推导的结果,和C++代码实现;至于具体推导过程,请参阅
Jerry D. Scargle, Studies in Astronomical Time Series Analysis. II. Statistical Aspect of Spectral Analysis of Unevenly Spaced Data, the Astrophysical Journal, vol. 263, pp. 835--853
这里不再多说。
Lomb方法
假设数据点集为(所有数学公式采用latex语法书写),
定义其数学期望和方差分别为
定义归一化周期图为
其中由下式定义
Lomb方法的C++实现:
1
//
lomb.hpp
2
3 #ifndef LOMB_HPP_INCLUDED__
4 #define LOMB_HPP_INCLUDED__
5
6 #include < vector >
7 using std::vector;
8
9 // Warning:
10 // If you would rather a self-defined type than
11 // a builtin type, these methods MUST be offered:
12 //
13 // operator=( const Type& other )
14 // operator=( const long double& val )
15 // operator+( const Type& lhs, const Type& rhs)
16 // operator-( const Type& lhs, const Type& rhs)
17 // operator*( const Type& lhs, const Type& rhs)
18 // operator/( const Type& lhs, const Type& rhs)
19 // sin( const Type& val )
20 // cos( const Type& val )
21 //
22 template
23 <
24 typename Type = long double
25 >
26 class Lomb
27 {
28 public :
29 vector < Type > spectrum() const ;
30
31 public :
32 Lomb( const vector < Type >& _h,
33 const vector < Type >& _t );
34 ~ Lomb();
35
36 private :
37 struct Lomb_Data;
38 Lomb_Data * lomb_data;
39 };
40
41 #include " lomb.tcc "
42
43 #endif // LOMB_HPP_INCLUDED__
44
2
3 #ifndef LOMB_HPP_INCLUDED__
4 #define LOMB_HPP_INCLUDED__
5
6 #include < vector >
7 using std::vector;
8
9 // Warning:
10 // If you would rather a self-defined type than
11 // a builtin type, these methods MUST be offered:
12 //
13 // operator=( const Type& other )
14 // operator=( const long double& val )
15 // operator+( const Type& lhs, const Type& rhs)
16 // operator-( const Type& lhs, const Type& rhs)
17 // operator*( const Type& lhs, const Type& rhs)
18 // operator/( const Type& lhs, const Type& rhs)
19 // sin( const Type& val )
20 // cos( const Type& val )
21 //
22 template
23 <
24 typename Type = long double
25 >
26 class Lomb
27 {
28 public :
29 vector < Type > spectrum() const ;
30
31 public :
32 Lomb( const vector < Type >& _h,
33 const vector < Type >& _t );
34 ~ Lomb();
35
36 private :
37 struct Lomb_Data;
38 Lomb_Data * lomb_data;
39 };
40
41 #include " lomb.tcc "
42
43 #endif // LOMB_HPP_INCLUDED__
44
//
lomb.tcc
#include " iterator.hpp "
#include < cassert >
#include < cmath >
#include < numeric >
#include < iterator >
#include < algorithm >
using namespace std;
template
<
typename Type
>
struct Lomb < Type > ::Lomb_Data
{
vector < Type > h;
vector < Type > t;
Type f() const ;
Type tau( const unsigned int ) const ;
Type e() const ;
Type d() const ;
};
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::f() const
{
const Type max = * ( max_element(
t.begin(), t.end() ) );
const Type min = * ( min_element(
t.begin(), t.end() ) );
const unsigned int N = h.size();
const Type ans = N / ( max - min ) ;
return ans;
}
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::tau( const unsigned int n ) const
{
const Type omega =
2 . 0L * 3 . 14159265358979L * ( this -> f() ) * n ;
const Type sin_ =
sin2_accumulate( t.begin(),
t.end(),
omega
);
const Type cos_ =
cos2_accumulate( t.begin(),
t.end(),
omega
);
const Type ans = atan( sin_ / cos_ ) / ( 2 . 0L * omega );
return ans;
}
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::e() const
{
const Type ans =
mean(
h.begin(),
h.end(),
Type_Keep < Type > ()
);
return ans;
}
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::d() const
{
const Type ans =
variance(
h.begin(),
h.end(),
Type_Keep < Type > ()
);
return ans;
}
template
<
typename Type
>
Lomb < Type > ::Lomb( const vector < Type >& _h,
const vector < Type >& _t
)
{
assert( _t.size() == _h.size() );
lomb_data = new Lomb_Data;
lomb_data -> h = _h;
lomb_data -> t = _t;
}
template
<
typename Type
>
Lomb < Type > :: ~ Lomb()
{
delete lomb_data;
}
template
<
typename Type
>
vector < Type > Lomb < Type > ::spectrum() const
{
const unsigned int N = ( * lomb_data).h.size();
const Type f = lomb_data -> f();
const Type e = lomb_data -> e();
const Type d = lomb_data -> d();
vector < Type > ans;
for ( unsigned int i = 0 ; i < N; ++ i )
{
const Type tau = lomb_data -> tau( i );
const Type omega = 6 . 283185307179586476L *
i * f;
const Type h_cos_square =
h_cos_square_accumulate(
( * lomb_data).h.begin(), ( * lomb_data).h.end(),
( * lomb_data).t.begin(), ( * lomb_data).t.end(),
e,
tau,
omega
);
const Type cos_square =
cos_square_accumulate(
( * lomb_data).t.begin(),
( * lomb_data).t.end(),
tau,
omega
);
const Type h_sin_square =
h_sin_square_accumulate(
( * lomb_data).h.begin(), ( * lomb_data).h.end(),
( * lomb_data).t.begin(), ( * lomb_data).t.end(),
e,
tau,
omega
);
const Type sin_square =
sin_square_accumulate(
( * lomb_data).t.begin(),
( * lomb_data).t.end(),
tau,
omega
);
ans.push_back( sqrt(
(
h_cos_square / cos_square +
h_sin_square / sin_square
) / ( 2 . 0L * d)
) / N
);
}
return ans;
}
#include " iterator.hpp "
#include < cassert >
#include < cmath >
#include < numeric >
#include < iterator >
#include < algorithm >
using namespace std;
template
<
typename Type
>
struct Lomb < Type > ::Lomb_Data
{
vector < Type > h;
vector < Type > t;
Type f() const ;
Type tau( const unsigned int ) const ;
Type e() const ;
Type d() const ;
};
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::f() const
{
const Type max = * ( max_element(
t.begin(), t.end() ) );
const Type min = * ( min_element(
t.begin(), t.end() ) );
const unsigned int N = h.size();
const Type ans = N / ( max - min ) ;
return ans;
}
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::tau( const unsigned int n ) const
{
const Type omega =
2 . 0L * 3 . 14159265358979L * ( this -> f() ) * n ;
const Type sin_ =
sin2_accumulate( t.begin(),
t.end(),
omega
);
const Type cos_ =
cos2_accumulate( t.begin(),
t.end(),
omega
);
const Type ans = atan( sin_ / cos_ ) / ( 2 . 0L * omega );
return ans;
}
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::e() const
{
const Type ans =
mean(
h.begin(),
h.end(),
Type_Keep < Type > ()
);
return ans;
}
template
<
typename Type
>
Type Lomb < Type > ::Lomb_Data::d() const
{
const Type ans =
variance(
h.begin(),
h.end(),
Type_Keep < Type > ()
);
return ans;
}
template
<
typename Type
>
Lomb < Type > ::Lomb( const vector < Type >& _h,
const vector < Type >& _t
)
{
assert( _t.size() == _h.size() );
lomb_data = new Lomb_Data;
lomb_data -> h = _h;
lomb_data -> t = _t;
}
template
<
typename Type
>
Lomb < Type > :: ~ Lomb()
{
delete lomb_data;
}
template
<
typename Type
>
vector < Type > Lomb < Type > ::spectrum() const
{
const unsigned int N = ( * lomb_data).h.size();
const Type f = lomb_data -> f();
const Type e = lomb_data -> e();
const Type d = lomb_data -> d();
vector < Type > ans;
for ( unsigned int i = 0 ; i < N; ++ i )
{
const Type tau = lomb_data -> tau( i );
const Type omega = 6 . 283185307179586476L *
i * f;
const Type h_cos_square =
h_cos_square_accumulate(
( * lomb_data).h.begin(), ( * lomb_data).h.end(),
( * lomb_data).t.begin(), ( * lomb_data).t.end(),
e,
tau,
omega
);
const Type cos_square =
cos_square_accumulate(
( * lomb_data).t.begin(),
( * lomb_data).t.end(),
tau,
omega
);
const Type h_sin_square =
h_sin_square_accumulate(
( * lomb_data).h.begin(), ( * lomb_data).h.end(),
( * lomb_data).t.begin(), ( * lomb_data).t.end(),
e,
tau,
omega
);
const Type sin_square =
sin_square_accumulate(
( * lomb_data).t.begin(),
( * lomb_data).t.end(),
tau,
omega
);
ans.push_back( sqrt(
(
h_cos_square / cos_square +
h_sin_square / sin_square
) / ( 2 . 0L * d)
) / N
);
}
return ans;
}
1
//
iterator.hpp
2
3 #ifndef ITERATOR_HPP_INCLUDED__
4 #define ITERATOR_HPP_INCLUDED__
5
6 // this struct is just employed
7 // to keep the Type information
8 template
9 <
10 typename Type
11 >
12 struct Type_Keep;
13
14
15 // calculate
16 // \sum_{i} \sin 2 \omega t_i
17 template
18 <
19 typename InputItor,
20 typename Type
21 >
22 Type sin2_accumulate(
23 InputItor begin,
24 InputItor end,
25 Type omega
26 );
27
28 // calculate
29 // \sum_{i} \cos 2 \omega t_i
30 template
31 <
32 typename InputItor,
33 typename Type
34 >
35 Type cos2_accumulate(
36 InputItor begin,
37 InputItor end,
38 Type omega
39 );
40
41 // calculate
42 // \frac{1}{N} \sum_{i} h_i
43 template
44 <
45 typename InputItor,
46 typename Type
47 >
48 Type mean(
49 InputItor begin,
50 InputItor end,
51 Type_Keep < Type >
52 );
53
54 // calculate
55 // \frac{1}{N-1} \sum_{i}(h_i - h)^{2}
56 template
57 <
58 typename InputItor,
59 typename Type
60 >
61 Type variance(
62 InputItor begin,
63 InputItor end,
64 Type_Keep < Type >
65 );
66
67 // calcuate
68 // [\sum_i (h_i - h) \sin \omega (t_i - \tau)]^{2}
69 template
70 <
71 typename Type,
72 typename InputItor
73 >
74 Type h_sin_square_accumulate( InputItor h_start, InputItor h_end,
75 InputItor t_start, InputItor t_end,
76 Type h,
77 Type tau,
78 Type omega
79 );
80
81 // calcuate
82 // [\sum_i (h_i - h) \cos \omega (t_i - \tau)]^{2}
83 template
84 <
85 typename Type,
86 typename InputItor
87 >
88 Type h_cos_square_accumulate( InputItor h_start, InputItor h_end,
89 InputItor t_start, InputItor t_end,
90 Type h,
91 Type tau,
92 Type omega
93 );
94
95 // calculate
96 // \sum_{i} \cos ^{2} \omega (t_i - \tau)
97 template
98 <
99 typename Type,
100 typename InputItor
101 >
102 Type cos_square_accumulate( InputItor t_start,
103 InputItor t_end,
104 Type tau,
105 Type omega
106 );
107
108 // calculate
109 // \sum_{i} \cos ^{2} \omega (t_i - \tau)
110 template
111 <
112 typename Type,
113 typename InputItor
114 >
115 Type sin_square_accumulate( InputItor t_start,
116 InputItor t_end,
117 Type tau,
118 Type omega
119 );
120
121 #include " iterator.tcc "
122
123 #endif // ITERATOR_HPP_INCLUDED__
124
2
3 #ifndef ITERATOR_HPP_INCLUDED__
4 #define ITERATOR_HPP_INCLUDED__
5
6 // this struct is just employed
7 // to keep the Type information
8 template
9 <
10 typename Type
11 >
12 struct Type_Keep;
13
14
15 // calculate
16 // \sum_{i} \sin 2 \omega t_i
17 template
18 <
19 typename InputItor,
20 typename Type
21 >
22 Type sin2_accumulate(
23 InputItor begin,
24 InputItor end,
25 Type omega
26 );
27
28 // calculate
29 // \sum_{i} \cos 2 \omega t_i
30 template
31 <
32 typename InputItor,
33 typename Type
34 >
35 Type cos2_accumulate(
36 InputItor begin,
37 InputItor end,
38 Type omega
39 );
40
41 // calculate
42 // \frac{1}{N} \sum_{i} h_i
43 template
44 <
45 typename InputItor,
46 typename Type
47 >
48 Type mean(
49 InputItor begin,
50 InputItor end,
51 Type_Keep < Type >
52 );
53
54 // calculate
55 // \frac{1}{N-1} \sum_{i}(h_i - h)^{2}
56 template
57 <
58 typename InputItor,
59 typename Type
60 >
61 Type variance(
62 InputItor begin,
63 InputItor end,
64 Type_Keep < Type >
65 );
66
67 // calcuate
68 // [\sum_i (h_i - h) \sin \omega (t_i - \tau)]^{2}
69 template
70 <
71 typename Type,
72 typename InputItor
73 >
74 Type h_sin_square_accumulate( InputItor h_start, InputItor h_end,
75 InputItor t_start, InputItor t_end,
76 Type h,
77 Type tau,
78 Type omega
79 );
80
81 // calcuate
82 // [\sum_i (h_i - h) \cos \omega (t_i - \tau)]^{2}
83 template
84 <
85 typename Type,
86 typename InputItor
87 >
88 Type h_cos_square_accumulate( InputItor h_start, InputItor h_end,
89 InputItor t_start, InputItor t_end,
90 Type h,
91 Type tau,
92 Type omega
93 );
94
95 // calculate
96 // \sum_{i} \cos ^{2} \omega (t_i - \tau)
97 template
98 <
99 typename Type,
100 typename InputItor
101 >
102 Type cos_square_accumulate( InputItor t_start,
103 InputItor t_end,
104 Type tau,
105 Type omega
106 );
107
108 // calculate
109 // \sum_{i} \cos ^{2} \omega (t_i - \tau)
110 template
111 <
112 typename Type,
113 typename InputItor
114 >
115 Type sin_square_accumulate( InputItor t_start,
116 InputItor t_end,
117 Type tau,
118 Type omega
119 );
120
121 #include " iterator.tcc "
122
123 #endif // ITERATOR_HPP_INCLUDED__
124
//
iterator.tcc
#include < cmath >
template
<
typename Type
>
struct Type_Keep
{
typedef Type T;
};
template
<
typename Type
>
struct Sin
{
Type operator ()( const Type val ) const
{
return sin( val );
}
};
template
<
typename Type
>
struct Cos
{
Type operator ()( const Type val ) const
{
return cos( val );
}
};
template
<
typename InputItor,
typename Type,
typename Function
>
static Type f2_accumulate(
InputItor begin,
InputItor end,
Type omega,
Function f
)
{
Type ans = Type();
while ( begin != end )
{
ans += f( 2 . 0L * omega * ( * begin ++ ) );
}
return ans;
}
template
<
typename InputItor,
typename Type
>
Type sin2_accumulate(
InputItor begin,
InputItor end,
Type omega
)
{
return f2_accumulate(
begin,
end,
omega,
Sin < Type > ()
);
}
template
<
typename InputItor,
typename Type
>
Type cos2_accumulate(
InputItor begin,
InputItor end,
Type omega
)
{
return f2_accumulate(
begin,
end,
omega,
Sin < Type > ()
);
}
template
<
typename InputItor,
typename Type
>
Type mean(
InputItor begin,
InputItor end,
Type_Keep < Type >
)
{
Type sum = Type();
unsigned int cnt = 0 ;
while ( begin != end )
{
sum += * begin ++ ;
++ cnt;
}
return sum / cnt;
}
template
<
typename InputItor,
typename Type
>
static Type diff_square_accumulate(
InputItor begin,
InputItor end,
Type mean
)
{
Type ans = Type();
while ( begin != end )
{
ans += ( mean - * begin ) * ( mean - * begin ) ;
++ begin;
}
return ans;
}
template
<
typename InputItor
>
static unsigned int difference(
InputItor begin,
InputItor end
)
{
unsigned int cnt = 0 ;
while ( begin ++ != end )
++ cnt;
return cnt;
}
template
<
typename InputItor,
typename Type
>
Type variance(
InputItor begin,
InputItor end,
Type_Keep < Type >
)
{
const Type average =
mean( begin, end, Type_Keep < long double > () );
const Type power =
diff_square_accumulate( begin, end, average );
const unsigned int size =
difference( begin, end );
const Type ans = power / (size - 1 );
return ans;
}
template
<
typename Type,
typename InputItor,
typename Function
>
static Type h_f_square_accumulate( InputItor h_start, InputItor h_end,
InputItor t_start, InputItor t_end,
Type h,
Type tau,
Type omega,
Function f
)
{
Type ans = Type();
while ( ( h_start != h_end ) && ( t_start != t_end ) )
{
ans += ( * h_start ++ - h ) * f( omega * ( * t_start ++ - tau) );
}
return ans * ans;
}
template
<
typename Type,
typename InputItor
>
Type h_sin_square_accumulate( InputItor h_start, InputItor h_end,
InputItor t_start, InputItor t_end,
Type h,
Type tau,
Type omega
)
{
return h_f_square_accumulate(
h_start, h_end,
t_start, t_end,
h,
tau,
omega,
Sin < Type > ()
);
}
template
<
typename Type,
typename InputItor
>
Type h_cos_square_accumulate( InputItor h_start, InputItor h_end,
InputItor t_start, InputItor t_end,
Type h,
Type tau,
Type omega
)
{
return h_f_square_accumulate(
h_start, h_end,
t_start, t_end,
h,
tau,
omega,
Cos < Type > ()
);
}
template
<
typename Type,
typename InputItor,
typename Function
>
static Type f_square_accumulate( InputItor t_start,
InputItor t_end,
Type tau,
Type omega,
Function f
)
{
Type ans = Type();
while ( t_start != t_end )
{
const Type tmp = f( omega * ( * t_start ++ - tau ) );
ans += tmp * tmp;
}
return ans;
}
template
<
typename Type,
typename InputItor
>
Type cos_square_accumulate( InputItor t_start,
InputItor t_end,
Type tau,
Type omega
)
{
return f_square_accumulate(
t_start,
t_end,
tau,
omega,
Cos < Type > ()
);
}
template
<
typename Type,
typename InputItor
>
Type sin_square_accumulate( InputItor t_start,
InputItor t_end,
Type tau,
Type omega
)
{
return f_square_accumulate(
t_start,
t_end,
tau,
omega,
Sin < Type > ()
);
}
#include < cmath >
template
<
typename Type
>
struct Type_Keep
{
typedef Type T;
};
template
<
typename Type
>
struct Sin
{
Type operator ()( const Type val ) const
{
return sin( val );
}
};
template
<
typename Type
>
struct Cos
{
Type operator ()( const Type val ) const
{
return cos( val );
}
};
template
<
typename InputItor,
typename Type,
typename Function
>
static Type f2_accumulate(
InputItor begin,
InputItor end,
Type omega,
Function f
)
{
Type ans = Type();
while ( begin != end )
{
ans += f( 2 . 0L * omega * ( * begin ++ ) );
}
return ans;
}
template
<
typename InputItor,
typename Type
>
Type sin2_accumulate(
InputItor begin,
InputItor end,
Type omega
)
{
return f2_accumulate(
begin,
end,
omega,
Sin < Type > ()
);
}
template
<
typename InputItor,
typename Type
>
Type cos2_accumulate(
InputItor begin,
InputItor end,
Type omega
)
{
return f2_accumulate(
begin,
end,
omega,
Sin < Type > ()
);
}
template
<
typename InputItor,
typename Type
>
Type mean(
InputItor begin,
InputItor end,
Type_Keep < Type >
)
{
Type sum = Type();
unsigned int cnt = 0 ;
while ( begin != end )
{
sum += * begin ++ ;
++ cnt;
}
return sum / cnt;
}
template
<
typename InputItor,
typename Type
>
static Type diff_square_accumulate(
InputItor begin,
InputItor end,
Type mean
)
{
Type ans = Type();
while ( begin != end )
{
ans += ( mean - * begin ) * ( mean - * begin ) ;
++ begin;
}
return ans;
}
template
<
typename InputItor
>
static unsigned int difference(
InputItor begin,
InputItor end
)
{
unsigned int cnt = 0 ;
while ( begin ++ != end )
++ cnt;
return cnt;
}
template
<
typename InputItor,
typename Type
>
Type variance(
InputItor begin,
InputItor end,
Type_Keep < Type >
)
{
const Type average =
mean( begin, end, Type_Keep < long double > () );
const Type power =
diff_square_accumulate( begin, end, average );
const unsigned int size =
difference( begin, end );
const Type ans = power / (size - 1 );
return ans;
}
template
<
typename Type,
typename InputItor,
typename Function
>
static Type h_f_square_accumulate( InputItor h_start, InputItor h_end,
InputItor t_start, InputItor t_end,
Type h,
Type tau,
Type omega,
Function f
)
{
Type ans = Type();
while ( ( h_start != h_end ) && ( t_start != t_end ) )
{
ans += ( * h_start ++ - h ) * f( omega * ( * t_start ++ - tau) );
}
return ans * ans;
}
template
<
typename Type,
typename InputItor
>
Type h_sin_square_accumulate( InputItor h_start, InputItor h_end,
InputItor t_start, InputItor t_end,
Type h,
Type tau,
Type omega
)
{
return h_f_square_accumulate(
h_start, h_end,
t_start, t_end,
h,
tau,
omega,
Sin < Type > ()
);
}
template
<
typename Type,
typename InputItor
>
Type h_cos_square_accumulate( InputItor h_start, InputItor h_end,
InputItor t_start, InputItor t_end,
Type h,
Type tau,
Type omega
)
{
return h_f_square_accumulate(
h_start, h_end,
t_start, t_end,
h,
tau,
omega,
Cos < Type > ()
);
}
template
<
typename Type,
typename InputItor,
typename Function
>
static Type f_square_accumulate( InputItor t_start,
InputItor t_end,
Type tau,
Type omega,
Function f
)
{
Type ans = Type();
while ( t_start != t_end )
{
const Type tmp = f( omega * ( * t_start ++ - tau ) );
ans += tmp * tmp;
}
return ans;
}
template
<
typename Type,
typename InputItor
>
Type cos_square_accumulate( InputItor t_start,
InputItor t_end,
Type tau,
Type omega
)
{
return f_square_accumulate(
t_start,
t_end,
tau,
omega,
Cos < Type > ()
);
}
template
<
typename Type,
typename InputItor
>
Type sin_square_accumulate( InputItor t_start,
InputItor t_end,
Type tau,
Type omega
)
{
return f_square_accumulate(
t_start,
t_end,
tau,
omega,
Sin < Type > ()
);
}
实例
下面这个例子中,将从文件phi.dat中输入采样数据,从文件rem.dat中输入采样空间间隔,使用Lomb算法处理后,得到的空间频谱将输出到文件spectrum.dat中去
1
#include
"
lomb.hpp
"
2
3 #include < iostream >
4 #include < fstream >
5 #include < vector >
6 #include < iterator >
7 #include < algorithm >
8
9 using namespace std;
10
11 int main()
12 {
13 ifstream phi_src( " phi.dat " );
14 ifstream rem_src( " rem.dat " );
15 ofstream spectrum_dst( " spectrum.dat " );
16
17 vector < long double > h;
18 vector < long double > t;
19
20 copy( istream_iterator < long double > (phi_src), istream_iterator < long double > (), back_inserter(t) );
21 copy( istream_iterator < long double > (rem_src), istream_iterator < long double > (), back_inserter(h) );
22
23 Lomb < long double >* lomb = new Lomb < long double > ( h, t );
24
25 vector < long double > v_spectrum = lomb -> spectrum();
26 copy( v_spectrum.begin(), v_spectrum.end(), ostream_iterator < long double > (spectrum_dst, " \n " ) );
27
28 delete lomb;
29 phi_src.close();
30 rem_src.close();
31 spectrum_dst.close();
32
33 return 0 ;
34 }
35
2
3 #include < iostream >
4 #include < fstream >
5 #include < vector >
6 #include < iterator >
7 #include < algorithm >
8
9 using namespace std;
10
11 int main()
12 {
13 ifstream phi_src( " phi.dat " );
14 ifstream rem_src( " rem.dat " );
15 ofstream spectrum_dst( " spectrum.dat " );
16
17 vector < long double > h;
18 vector < long double > t;
19
20 copy( istream_iterator < long double > (phi_src), istream_iterator < long double > (), back_inserter(t) );
21 copy( istream_iterator < long double > (rem_src), istream_iterator < long double > (), back_inserter(h) );
22
23 Lomb < long double >* lomb = new Lomb < long double > ( h, t );
24
25 vector < long double > v_spectrum = lomb -> spectrum();
26 copy( v_spectrum.begin(), v_spectrum.end(), ostream_iterator < long double > (spectrum_dst, " \n " ) );
27
28 delete lomb;
29 phi_src.close();
30 rem_src.close();
31 spectrum_dst.close();
32
33 return 0 ;
34 }
35
备注
Lomb算法的复杂度是O(n^2),若采样数据比较长,可以采用fft方法简化复杂度到O(nlogn),与大数乘法中的fft用法一致,此处不再多说。