爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 5744|回复: 12

[求助] 李建平eof程序问题

[复制链接]

新浪微博达人勋

发表于 2014-5-9 22:24:27 | 显示全部楼层 |阅读模式

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

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

x
李建平eof程序问题


当格点数小于时间长度时候 为什么总显示数组越界?? 没法用吗?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-7-25 16:57:55 | 显示全部楼层
同问  ,我也不知道 啊
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2014-5-9 23:54:50 | 显示全部楼层
李老师不会犯那种低级错误
估计是那个关于矩阵的参数你没改,自己好好看变量声明吧
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-5-10 09:30:43 | 显示全部楼层
lqouc 发表于 2014-5-9 23:54
李老师不会犯那种低级错误
估计是那个关于矩阵的参数你没改,自己好好看变量声明吧

不是  之前用的数据格点数大于时间长度时候 很快出结果

现在换了数据 换了格点数就不行了

搜本论坛也发现了别人也出现过这个问题

但是没有解决办法
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-5-10 17:14:29 | 显示全部楼层
丑八怪周柏宇 发表于 2014-5-10 09:30
不是  之前用的数据格点数大于时间长度时候 很快出结果

现在换了数据 换了格点数就不行了

我用的时候格点小于时间就可以,mnh这个参数你修改了么?
不行就把程序贴上来,纸上谈兵谁也帮不了你。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-5-13 18:00:50 | 显示全部楼层
lqouc 发表于 2014-5-10 17:14
我用的时候格点小于时间就可以,mnh这个参数你修改了么?
不行就把程序贴上来,纸上谈兵谁也帮不了你。

!        EOF:经验正交函数分解!“实现时空场的分离”具体可以参考黄嘉佑老师的《气象统计分析与预报方法》
!        这是来自“lijianping”老师的EOF分解程序,在此对李建平老师表示感谢O(∩_∩)O~
!        相关参数说明
!        m:格点数
!        n:时间长度
!        mnl:模态数                        
!        ks:    [1]-1表示对原场EOF;
!                [2]0表示多距平场EOF;
!                [3]1表示对归一化场EOF。
!        "test.txt"        :需要分解的时空场
!        "er.txt":存放解释方差        [1]:er(mnl,1)特征值——        [2]:er(mnl,2)累计特征值——        [3]:er(mnl,3)解释方差——        [4]:er(mnl,4)累计解释方差!【20120922补充:解释方差就是对特征值的归一化】
!        "ecof.txt":存放时间系数------每一列是一个模态
!        "egvt.txt":存放各个模态的空间向量场------每一列是一个模态  
parameter(m=483,n=600,mnl=600,ks=0)
real x(m,n),egvt(m,mnl),ecof(mnl,n),er(mnl,4)     , c
        open(1,file='dfai.dat',form='unformatted',access='direct',recl=m)
        do j=1,n
           read(1,rec=j) (x(i,j),i=1,m)
        enddo
        close(1)

call eof(m,n,mnl,x,ks,er,egvt,ecof)
        open(2,file="er.txt")

        do i=1,mnl

        write(2,"(4f30.8)") (er(i,j),j=1,4)

        enddo

        close(2)

        open(3,file="ecof.txt")
        do j=1,n
        write(3,"(<mnl>f20.6)") (ecof(i,j),i=1,mnl)
        enddo
        close(3)
        open(4,file="egvt.txt")
        do i=1,m
        write(4,"(<mnl>f20.6)") (egvt(i,j),j=1,mnl)
        enddo
        close(4)
print*,"-------------------------------"
print*,"这是来自李建平老师的EOF分解程序"
print*,"http://bbs.06climate.com整理制作"
print*,"-------------------------------"
end
!***************************************************************************
        subroutine eof(m,n,mnl,f,ks,er,egvt,ecof)
                implicit none
                integer*4                                ::        m,n,mnl,ks
                real*4                                        ::        f(m,n),er(mnl,4),egvt(m,mnl),ecof(mnl,n)
                real*4,allocatable                ::        cov(:,:),s(:,:),d(:)
                call transf(m,n,f,ks)
                allocate(cov(mnl,mnl))
                call crossproduct(m,n,mnl,f,cov)
                allocate(s(mnl,mnl))
                allocate(d(mnl))
                call jacobi(mnl,cov,s,d,0.00001)
                call arrang(mnl,d,s,er)
                call tcoeff(m,n,mnl,f,s,er,egvt,ecof)
                return
        end
        subroutine transf(m,n,f,ks)
                implicit none
                integer*4                                        ::        m,n,ks  , c
                real*4                                                ::        f(m,n)
                real*4,allocatable                        ::        fw(:),wn(:),fx(:)
                integer*4                                        ::        i0,i,j
                real*4                                                ::        af,sf,vf
                allocate(fw(n))
                allocate(wn(m))
                i0=0
                do i=1,m
                        do j=1,n
                                fw(j)=f(i,j)
                        enddo
                        call meanvar(n,fw,af,sf,vf)
                        if(sf.eq.0.)then
                                i0=i0+1
                                wn(i0)=i

                                            end if
                enddo
!               if(i0.ne.0)then      !!!!!!!!!!!!!!  处理缺省值    !!!!!!!!!!!!!!!!!
                        
!               endif            
                if(ks.eq.-1)return
                if(ks.eq.0)then
                        do i=1,m
                        do j=1,n
                                fw(j)=f(i,j)
                        enddo
                        call meanvar(n,fw,af,sf,vf)
                        do j=1,n
                                f(i,j)=f(i,j)-af
                        enddo
                        enddo
                        return
                endif
                if(ks.eq.1)then
                        do i=1,m
                        do j=1,n
                                fw(j)=f(i,j)
                        enddo
                        call meanvar(n,fw,af,sf,vf)   ! sf 为标准差,vf为方差
                        if(sf==0.0)then
                        do j=1,n
                             f(i,j)=0.0
                        enddo
                        else
                        do j=1,n
                             f(i,j)=(f(i,j)-af)/sf
                        enddo
                        endif
                        enddo
                endif
                return
        end
        subroutine crossproduct(m,n,mnl,f,cov)
                implicit none
                integer*4                ::        m,n,mnl
                real*4                        ::        f(m,n),cov(mnl,mnl)
                integer*4                ::        i,j,is,js
                        if((n-m)<0)then
                        do i=1,mnl
                        do j=i,mnl
                                cov(i,j)=0.0
                                do is=1,m
                                        cov(i,j)=cov(i,j)+f(is,i)*f(is,j)
                                enddo
                                cov(j,i)=cov(i,j)
                        enddo
                        enddo
                        else
                        do i=1,mnl
                        do j=i,mnl
                                cov(i,j)=0.0
                                do js=1,n
                                        cov(i,j)=cov(i,j)+f(i,js)*f(j,js)
                                enddo
                                cov(j,i)=cov(i,j)
                        enddo
                        enddo
                        endif
                return        
        end
        subroutine jacobi(m,a,s,d,eps)
                implicit none
                integer*4                ::        m
                real*4                        ::        a(m,m),s(m,m),d(m),eps
                integer*4                ::        i,j,i1,l,iq,iq1,ip
                real*4                        ::        g,s1,s2,s3,v1,v2,v3,u,st,ct
                        s=0.0
                        do i=1,m
                                s(i,i)=1.0
                        enddo
                        g=0.
                        do i=2,m
                                i1=i-1
                                do j=1,i1
                                g=g+2.0*a(i,j)*a(i,j)
                                enddo
                        enddo
                        s1=sqrt(g)
                        s2=eps/float(m)*s1
                        s3=s1
                        l=0
50                        s3=s3/float(m)
60                        do iq=2,m
                                iq1=iq-1                                       
                                do ip=1,iq1
                                        if(abs(a(ip,iq)).lt.s3) exit
                                        l=1
                                        v1=a(ip,ip)
                                        v2=a(ip,iq)
                                        v3=a(iq,iq)
                                        u=0.5*(v1-v3)
                                        if(u.eq.0.0) g=1.
                                        if(abs(u).ge.1e-10) g=-sign(1.,u)*v2/sqrt(v2*v2+u*u)
                                        st=g/sqrt(2.*(1.+sqrt(1.-g*g)))
                                        ct=sqrt(1.-st*st)
                                        do i=1,m
                                                g=a(i,ip)*ct-a(i,iq)*st
                                                a(i,iq)=a(i,ip)*st+a(i,iq)*ct
                                                a(i,ip)=g
                                                g=s(i,ip)*ct-s(i,iq)*st
                                                s(i,iq)=s(i,ip)*st+s(i,iq)*ct
                                                s(i,ip)=g
                                        enddo
                                        do i=1,m
                                                a(ip,i)=a(i,ip)
                                                a(iq,i)=a(i,iq)
                                        enddo
                                        g=2.*v2*st*ct
                                        a(ip,ip)=v1*ct*ct+v3*st*st-g
                                        a(iq,iq)=v1*st*st+v3*ct*ct+g
                                        a(ip,iq)=(v1-v3)*st*ct+v2*(ct*ct-st*st)
                                        a(iq,ip)=a(ip,iq)
                                enddo
                        enddo
                        if((l-1)==0)then
                                l=0
                                go to 60
                        else
                                go to 150
                        endif
150                        if(s3.gt.s2) then
                         goto 50
                        end if
                        do i=1,m
                                d(i)=a(i,i)
                        enddo
                return
        end
        subroutine arrang(mnl,d,s,er)
                implicit none
                integer*4                ::        mnl
                real*4                        ::        d(mnl),s(mnl,mnl),er(mnl,4)
                integer*4                ::        i,mnl1,k1,k2
                real*4                        ::        c,tr
                tr=0.0
                do i=1,mnl
                        tr=tr+d(i)
                        er(i,1)=d(i)
                enddo
                mnl1=mnl-1
                do k1=mnl1,1,-1
                        do k2=k1,mnl1
                        if(er(k2,1).lt.er(k2+1,1)) then
                        c=er(k2+1,1)
                        er(k2+1,1)=er(k2,1)
                        er(k2,1)=c                        
                        do i=1,mnl
                                c=s(i,k2+1)
                                s(i,k2+1)=s(i,k2)
                                s(i,k2)=c
                        enddo
                        endif
                        enddo
                enddo
                er(1,2)=er(1,1)
                do i=2,mnl
                        er(i,2)=er(i-1,2)+er(i,1)
                enddo
                do i=1,mnl
                        er(i,3)=er(i,1)/tr
                        er(i,4)=er(i,2)/tr
                enddo
                return
        end
        subroutine tcoeff(m,n,mnl,f,s,er,egvt,ecof)
                implicit none
                integer*4                                        ::        m,n,mnl
                real*4                                                ::        f(m,n),s(mnl,mnl),er(mnl,4),egvt(m,mnl),ecof(mnl,n)
                real*4,allocatable                        ::        v(:)
                integer*4                                        ::        i,j,js,is
                real*4                                                ::        c
                allocate(v(mnl))
                do j=1,mnl
                        do i=1,m
                                egvt(i,j)=0.
                        enddo
                        do i=1,n
                                ecof(j,i)=0.
                        enddo
                enddo
                do j=1,mnl
                        c=0.
                        do i=1,mnl
                                c=c+s(i,j)*s(i,j)
                        enddo
                        c=sqrt(c)
                        do i=1,mnl
                                s(i,j)=s(i,j)/c
                        enddo
                enddo
                if(m.le.n) then
                        do js=1,mnl
                                do i=1,m
                                        egvt(i,js)=s(i,js)
                                enddo
                        enddo
                        do j=1,n
                                do i=1,m
                                v(i)=f(i,j)
                                enddo
                                do is=1,mnl
                                do i=1,m
                                ecof(is,j)=ecof(is,j)+v(i)*s(i,is)
                                enddo
                                enddo
                        enddo
                else
                        do i=1,m
                                do j=1,n
                                v(j)=f(i,j)
                                enddo
                                do js=1,mnl
                                do j=1,n
                                egvt(i,js)=egvt(i,js)+v(j)*s(j,js)
                                enddo
                                enddo
                        enddo
                        do js=1,mnl
                                do j=1,n
                                ecof(js,j)=s(j,js)*sqrt(abs(er(js,1)))
                                enddo
                                do i=1,m
                                egvt(i,js)=egvt(i,js)/sqrt(abs(er(js,1)))
                                enddo
                        enddo
                endif
                return        
        end
        subroutine meanvar(n,x,ax,sx,vx)
                implicit none
                integer*4                ::        n
                real*4                        ::        x(n)
                real*4                        ::        ax,vx,sx
                integer*4                ::        i
                ax=0.
                vx=0.
                sx=0.
                do i=1,n
                        ax=ax+x(i)
                enddo                        
                ax=ax/float(n)
                do i=1,n
                        vx=vx+(x(i)-ax)**2
                enddo
                vx=vx/float(n)
                sx=sqrt(vx)
                return
        end
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-5-13 18:03:49 | 显示全部楼层
lqouc 发表于 2014-5-10 17:14
我用的时候格点小于时间就可以,mnh这个参数你修改了么?
不行就把程序贴上来,纸上谈兵谁也帮不了你。


forrtl: severe (161): Program Exception - array bounds exceeded
Image              PC        Routine            Line        Source
eof.exe            00402B39  Unknown               Unknown  Unknown

Incrementally linked image--PC correlation disabled.
Press any key to continue



显示的就是这样的  不知道应该怎么改  如果格点大于600 就能出结果
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-5-13 18:16:05 | 显示全部楼层
好吧,我的程序跟你的不大一样,你这个没有可以改矩阵的那个参数,给你个链接,换个程序用吧
http://bbs.06climate.com/forum.php?mod=viewthread&tid=13501
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-5-14 08:46:35 | 显示全部楼层
lqouc 发表于 2014-5-13 18:16
好吧,我的程序跟你的不大一样,你这个没有可以改矩阵的那个参数,给你个链接,换个程序用吧
http://bbs.0 ...

‘抱歉,本帖要求阅读权限高于 20 才能浏览’  
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-5-15 12:55:21 | 显示全部楼层
lqouc 发表于 2014-5-13 18:16
好吧,我的程序跟你的不大一样,你这个没有可以改矩阵的那个参数,给你个链接,换个程序用吧
http://bbs.0 ...

学长!你上次给我发的这个网址,我打不开,好像是级别不够!能不能贴到这里?或者邮件给我(agentcow@163.com)?谢谢学长!!!
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

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

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

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