爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 96389|回复: 112

[经验总结] 关于谐波滤波的简单原理与方法,还有fortran程序。

  [复制链接]

新浪微博达人勋

发表于 2013-1-17 21:13:54 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 lqouc 于 2013-1-17 22:55 编辑

之前有一次发过一个帖子,把自己编的关于空间谐波滤波的程序拿出来提问,结果有些朋友(@大果粒)想要了解这种滤波方法,我就在这里小小的总结一下,而且发现家园和资料站都没有关于谐波滤波的程序和原理,就顺便把程序也发上来。这些都是个人自己的思考,没有经过高水平人士的验证,不保证正确,而且程序也并不是很通用,就当时给初学者的一块敲门砖吧。
关于谐波滤波的目的,首先我们的气象数据有空间两维(水平)和时间一维,根据波动理论我们知道很多的空间波动和时间波动都包含在数据中,但是在分析的时候我们并不需要所有的信息,只要选取最重要的一部分就可以了。例如空间波动在对流层中对我们影响最大的是行星尺度波(纬圈0-3波)和天气尺度波(纬圈6-12波)。这样为了得到某一个波段的波动,我们需要进行滤波。(对于气象来说时间和空间是相对应的)
进行滤波的手段有很多,比如平均,滑动平均构造的滤波器,谐波滤波,甚至EOF方法。以位势高度来讨论,a:最简单的是平均,例如对数据进行月平均,这样就去除了要素中的快变成分,得到的数据不含有天气尺度波和中尺度波。b:滑动平均稍微高级一点,可以用来构造带通滤波器,保留什么样的波段就看你取多少点进行滑动平均了。c:谐波滤波在下面会仔细讲一下。dEOF其实也是可以做到滤波的,但是本质上讲不是用来滤波,它是把不同频率的波动按照方差贡献排列下来,通过不同模的时间系数来反映的,这样的好处就是,即便我们不清楚我们的数据中什么频率的波动影响最强,它也可以为你找到这个频率,并提取出来(而且也同时得到了时间变化哦)。
这里就是主要内容了,谐波滤波:
时域上的Fourier变换产生频率域上的谱分量。
空间域上的Fourier变换产生波数域上的谱分量。
谐波分析的基本原理,是将任意已知周期T的时间序列看作是由许多频率(周期)与基波频率(周期)成倍数的谐波叠加,基本周期等于序列的长度,即T=n,称为基波,其余各波称为谐波,他们的频率fkk=1,2,3……p)分别为基波频率的2,3,4……p倍,而它们的频率则分别为基波的1/2,1/3,1/4……,1/pp为谐波数)。因此,最短的周期为观测间隔的2倍。如果序列长度为n=24,基本周期就是T=24,其他各谐波周期就是24/2,24/3,…….,24/p。根据上述原理,具有任意基本周期T的时间(以时间为例)序列xt可以由下式给出:
                     QQ截图20130117224725.png           (1
A0是序列的算术平均值, QQ截图20130117224801.png 是各谐波的振幅 QQ截图20130117224904.png 是各谐波的波向角。每个谐波的周期为 QQ截图20130117224845.png ,称为基波周期,而 w为基频。对上面的式子做变换,有了
QQ截图20130117224943.png 2
QQ截图20130117224935.png
所以(2)可以写为 QQ截图20130117224956.png 3
谐波分析的目的,就是要确定系数 QQ截图20130117225024.png ,以便利用k个谐波来逼近原始序列。根据最小二乘原理和三角函数的正交性,可以得到
QQ截图20130117225037.png
其中 称为傅氏系数
当然fortran是不会积分的,我们把上面的式子改写为有限求和形式,则有
QQ截图20130117225053.png
这样我们就可以根据上面的原理和公式进行编程和滤波了。
  1. !这是一个空间滤波的程序,在这个程序里面我们利用ncep的2.5*2.5*17的日平均位势高度数据
  2. !目的是对位势高度的空间波动进行空间谐波滤波,得到空间行星尺度波和天气尺度波
  3. !当然这个程序并不是很好,权当是作为一个参考吧,我也是菜鸟。
  4. !强调一下,所谓的空间滤波只是对纬向方向的空间滤波,因为自由大气的平均状态是纬向风。
  5. program lbx
  6. implicit none
  7. real,dimension(1:144,1:73,1:17,1:365)::hgt  !这里是数据格式,x,y,z,t
  8. real,dimension(0:12,1:73,12:17,1:365)::a,b  !这个是傅氏系数,在这里只滤出0到12波
  9. real,dimension(1:144,1:73,12:17,1:365)::lb0t3,lb6t12   !这两个是行星尺度和天气尺度波动,是多个频率波动的叠加
  10. real,dimension(0:12,1:144,1:73,12:17,1:365)::lb
  11. real,parameter::w=2.5                       !这个是一个空间格距,通过这个可以计算数据出在空间中的位置
  12. integer,parameter::it=365                   !这里设置总时间长度,可以根据自己的需要更改,在这里我就算一年的
  13. integer::i,j,k,t,m,irec                     !这里一般分别代表x,y,z,t,波数,换行
  14. !第一步,读取数据
  15. open(11,file='hgt1998.dat',status='old',form='unformatted',access='direct',recl=144*73)
  16. irec=1
  17. do t=1,it
  18.   do k=1,17
  19.    read(11,rec=irec)((hgt(i,j,k,t),i=1,144),j=1,73)
  20.    irec=irec+1
  21.   end do
  22. end do
  23. close(11)
  24. print*,'*'
  25. !这就开始空间滤波了

  26. !第二步,对所有谐波的系数进行初始设置
  27. a=0
  28. b=0
  29. print*,'**'
  30. !第三步,计算每个谐波的系数(这里其实只算了上文最后有限求和公式的求和部分)
  31. do t=1,it
  32. do k=12,17
  33. do m=0,12
  34.   do j=1,73
  35.    do i=1,144
  36.     a(m,j,k,t)=a(m,j,k,t)+hgt(i,j,k,t)*cosd(m*w*i)
  37.     b(m,j,k,t)=b(m,j,k,t)+hgt(i,j,k,t)*sind(m*w*i)
  38.    end do
  39.   end do
  40. end do
  41. end do
  42. end do
  43. !再除以空间序列的长度(这里是上边没完成的平均)
  44. a=a/72
  45. b=b/72
  46. do t=1,it
  47. do k=12,17
  48. do j=1,73
  49.   a(0,j,k,t)=a(0,j,k,t)/2
  50. end do
  51. end do
  52. end do
  53. print*,'***'
  54. !第四步,累加各个谐波,得到各个波段的空间滤波场(这里就是得到了公式3中的某一个频率的谐波和基波的叠加,和公式并不一样的是这里只有一个谐波)
  55. do t=1,it
  56. do k=12,17
  57. do m=1,12
  58.   do j=1,73
  59.    do i=1,144
  60.    lb(m,i,j,k,t)=a(0,j,k,t)+a(m,j,k,t)*cosd(m*w*i)+b(m,j,k,t)*sind(m*w*i)
  61.    end do
  62.   end do
  63. end do
  64. end do
  65. end do

  66. !得到平均场即0波滤波
  67. do t=1,it
  68. do k=12,17
  69. do j=1,73
  70.   do i=1,144
  71.    lb(0,i,j,k,t)=a(0,j,k,t)
  72.   end do
  73. end do
  74. end do
  75. end do

  76. !得到0-3波和6-12波的空间滤波
  77. do t=1,it
  78. do k=12,17
  79. do j=1,73
  80.   do i=1,144
  81.    lb0t3(i,j,k,t)=lb(1,i,j,k,t)+lb(2,i,j,k,t)+lb(3,i,j,k,t)-2*lb(0,i,j,k,t)
  82.    lb6t12(i,j,k,t)=lb(6,i,j,k,t)+lb(7,i,j,k,t)+lb(8,i,j,k,t)+lb(9,i,j,k,t)+lb(10,i,j,k,t)+lb(11,i,j,k,t)+lb(12,i,j,k,t)-6*lb(0,i,j,k,t)
  83.   end do
  84. end do
  85. end do
  86. end do
  87. print*,'****'
  88. !第五步,结果输出(这里就是按照GrADS格式写的,可以直接写个ctl画图了)
  89. open(11,file='lb-all1998.dat',status='replace',form='unformatted',access='direct',recl=144*73)
  90. irec=1
  91. do t=1,it
  92. do m=0,12
  93.   do k=12,17
  94.   write(11,rec=irec)((lb(m,i,j,k,t),i=1,144),j=1,73)
  95.   irec=irec+1
  96.   end do
  97. end do
  98. do k=12,17
  99.   write(11,rec=irec)((lb0t3(i,j,k,t),i=1,144),j=1,73)
  100.   irec=irec+1
  101. end do
  102. do k=12,17
  103.   write(11,rec=irec)((lb6t12(i,j,k,t),i=1,144),j=1,73)
  104.   irec=irec+1
  105. end do
  106. end do
  107. close(11)

  108. print*,'ok!'
  109. !完成

  110. end program

这样就完成了,顺便附上参考资料:胡基福,《气象统计原理与方法》,青岛海洋大学出版社,青岛,1996
还有我们学校老师上课时给的两个例子的图,给大家看看效果
无标题.png 这是总场,行星波和天气波的。
啰啰嗦嗦写了这么多,主要是之前自己做这个的时候,找遍了网上也没有现成的程序,花了两天的时间弄这个,送给需要急用的朋友吧,但是建议大家还是自己好好的学学原理。另外程序编的不好,我不很擅长这个,希望高人能给改进下,最好写个字程序出来,我实在是懒得写了。
QQ截图20130117224926.png

评分

参与人数 1金钱 +20 贡献 +2 收起 理由
wlzhongouc + 20 + 2 不错啊 学习了

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-17 21:34:20 | 显示全部楼层
真给力!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-17 21:34:32 | 显示全部楼层
谢谢楼主,不过我根据你的程序算出来的形势是对的,可是值好像大好多倍,我试了差不多2-3倍,这个是什么问题呢?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-17 21:51:30 | 显示全部楼层

这个我也不是很清楚啊,我做的都还可以啊,这个程序我确实也没有验证过。你要的是单独某个谐波的么?如果是的话我的程序计算出来的都是叠加平均场的谐波。或者不妨说说你的数据使用的什么,我们一起改进下。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-17 21:52:44 | 显示全部楼层
@言深深求版主指点一下啊,我辛辛苦苦写了很久的共识怎么就贴不上去呢?这个没公式没法看啊。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-17 21:52:50 | 显示全部楼层
还有楼主的公式貌似没有上传成功呢,谢谢楼主~
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-17 22:09:38 | 显示全部楼层
lqouc 发表于 2013-1-17 21:51
这个我也不是很清楚啊,我做的都还可以啊,这个程序我确实也没有验证过。你要的是单独某个谐波的么?如果 ...

我就是用gfs资料,网格1*1的,按你的这样算算下来还有数值有问题的,也是算0-3波的值,要是看到公式就能知道问题在哪里了应该,不知道有没有文献出处?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 成长值: 0
发表于 2013-1-17 22:25:52 | 显示全部楼层
lqouc 发表于 2013-1-17 21:52
@言深深求版主指点一下啊,我辛辛苦苦写了很久的共识怎么就贴不上去呢?这个没公式没法看啊。

qq截图,做成图片,然后贴图片就ok了···论坛本身不支持公式呢······
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-17 22:59:42 | 显示全部楼层
大果粒 发表于 2013-1-17 22:09
我就是用gfs资料,网格1*1的,按你的这样算算下来还有数值有问题的,也是算0-3波的值,要是看到公式就能知 ...

现在有公式了,不过这个水印打得我好悲伤啊,凑活看吧,根据上下文合理推断一下。至于文献上面写了啊。胡基福的气象统计。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-17 23:12:23 | 显示全部楼层
为啥层数是12:17层啊??
解释下

还有3——6 的 波怎么办
你想提取行星尺度波和天气尺度波 ,也不包括这个
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表