爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 12339|回复: 26

[经验总结] 傲娇师兄开贴调程序总结帖(一)细节之处出真知

[复制链接]

新浪微博达人勋

发表于 2014-7-12 21:12:47 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 虫儿飞 于 2014-7-12 21:21 编辑

开贴调程序有不少天,调了几个程序吧,有些还没调出来,伤感!

今天先写第一个总结帖,细节的重要性。

下面给出一个实例程,是我调试之后的,但是还有未尽之处,但已经可以解决问题。

program stjp

integer*4,parameter:: x=90,y=62,t=53
integer*4 :: ix,iy,it
real*4,parameter :: undef = -9.9900000E+08
real*4 :: sm(x,y,t),s(x,y),ave(x,y),ano(x,y,t),sd(x,y),anosd(x,y,t),su(x,y),sum1(x,y),ave1(x,y)

open (10,file='stnew.grd',form='binary')
!!!   读数据
do iy=1,y
do ix=1,x
  do it=1,t
  read(10) sm(ix,iy,it)
  enddo
enddo
enddo

!!!   气候场
ave = 0.0
do iy=1,y
do ix=1,x
if(sm(ix,iy,1).ne.undef) then
  do it=1,t
  ave(ix,iy)=ave(ix,iy)+sm(ix,iy,it)/53.0
  enddo
else
ave(ix,iy) = undef
endif
  ! ave(ix,iy)=(su(ix,iy))/53.0
enddo
enddo

!!!   距平场

do iy=1,y
  do ix=1,x
  if(sm(ix,iy,1).ne.undef) then
  do it=1,t
    ano(ix,iy,it)=sm(ix,iy,it)-ave(ix,iy)
enddo
else
do it=1,t
    ano(ix,iy,it)=undef
enddo
endif

enddo
enddo

!!!   标准差
sd = 0.0
do iy=1,y
  do ix=1,x
  if(sm(ix,iy,1).ne.undef) then
   do it=1,t
    sd(ix,iy)=sd(ix,iy)+ano(ix,iy,it)**2/53.0
    enddo
    sd(ix,iy)=sqrt(sd(ix,iy))
    else
    sd(ix,iy)=undef
    endif

enddo
enddo  

!!!   标准化距平
sum1 =  0.0
do iy=1,y
  do ix=1,x
  if(sm(ix,iy,1).ne.undef) then
   do it=1,t
   anosd(ix,iy,it)=ano(ix,iy,it)/sd(ix,iy)
sum1(ix,iy)=sum1(ix,iy)+anosd(ix,iy,it)  
  enddo
  else
  do it=1,t
   anosd(ix,iy,it)=undef

  enddo
  sum1(ix,iy)=undef  
  endif
!!!!!!验证结果的正确性,因为标准化距平的平均值为0
enddo
enddo
print *,sum1

open (14,file='biaozhunhua.grd',form='binary')
open (15,file='biaozhunhua.txt')
do it=1,t
write(14)  ((anosd(ix,iy,it),ix=1,x),iy=1,y)
write(15,100)  ((anosd(ix,iy,it),ix=1,x),iy=1,y)
enddo

100 format(61f7.3)
end program

给出这个程序是想说明两个问题:
1、大家都会遇到求距平的问题,首先要求气候态平均场,那么这个地方就有一个小细节需要注意,就是除以样本的过程要放在累积的过程中,并且累积之前要注意将 累积量赋值为0。但是需要值本身比较小,就需要在累加完再除以样本量。这个不讲究的时候的确不讲究,但是讲究起来还是有那么点意思的,各位自己体会。
!!!   气候场
ave = 0.0
do iy=1,y
do ix=1,x
if(sm(ix,iy,1).ne.undef) then
  do it=1,t
  ave(ix,iy)=ave(ix,iy)+sm(ix,iy,it)/53.0
  enddo
else
ave(ix,iy) = undef
endif enddo
enddo

2、.for 和.f90格式不要混用,从开始到结束。

以上两点都强调了细节的重要性,但是不知道各位有没有体会。
把我之前写的两个贴引过来,大家瞧瞧吧。
fortran编程的一点小体
http://bbs.06climate.com/forum.p ... =16909&fromuid=2680
(出处: 气象家园)

fortran编程之算法篇
http://bbs.06climate.com/forum.p ... =17120&fromuid=2680
(出处: 气象家园)



评分

参与人数 2金钱 +19 贡献 +5 收起 理由
dlgyz + 4 很给力!
言深深 + 15 + 5

查看全部评分

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

新浪微博达人勋

发表于 2014-7-12 21:30:04 | 显示全部楼层
mark
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

 成长值: 0
发表于 2014-7-13 09:19:15 | 显示全部楼层
我需要补充两点:
1,累加过程中除以样本计算速度往往比较慢,尤其对于批量大数据的时候。乘/除法的计算单位大约是计算加法的20倍【前者计算一次大约200/300计算时长,后者只有10-20左右】,因此累加结束之后再求和,速度快一些;
2,53应该是时间吧?有时候时间的里面可能有缺测,比如靠近极低的海温,在冬季的时候可能由于结冰而没有数值,需要判断一下,如果有缺测的,就需要扣除这一部分的。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-7-13 10:16:03 | 显示全部楼层
给傲娇师兄和深深点个赞,细节决定成败,学习了
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-7-13 10:41:45 | 显示全部楼层
很好地帖子,写程序实现想法是个细致活,期待后续.......
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-7-16 11:54:09 | 显示全部楼层
看来楼主没有很好的利用fortran的内置函数。例如::
对于数组arr,其和可以这么做:: total=SUM (arr, arr.NE.undef)
数组相减::
where(( arr1 .NE.undef) .AND. (arr2.NE.undef))
         arr=arr1-arr2
endwhere
统计个数:: nvals=COUNT(arr.NE.undef)
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-7-18 14:27:36 | 显示全部楼层
细节决定成败啊,期待后续
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-7-24 15:35:21 | 显示全部楼层
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-8-2 15:24:52 | 显示全部楼层
fortran的内置函数还是简单些,对缺测值的判断是不是不全面呀
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-8-4 11:22:09 | 显示全部楼层
MARK之
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

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

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

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