回 帖 发 新 帖 刷新版面

主题:各位帮忙看看我的问题!

main.f90:

program main
    USE VAR
    IMPLICIT NONE
    ! DATA BETA /8*0/ DATA initializaion is not allowed
    ! When the variable is defined in a module,So:
    INTEGER::I ! cycle index
    REAL::GRA(DIM2)!GRADIENT
    REAL::D(DIM2) !for use of d=-b
    REAL::LD,PHO
    REAL::K,ALPHA0,ALPHA

    LOGICAL::ALIVE
    LAMBDA=REAL(2)

    BETA=(/(0.0,I=1,8)/)
    OPEN(10,FILE="G:\lasso.txt") !write(t(matrix(temp,67,9)),"G:\\lasso.txt",ncolumns=9)
    INQUIRE(FILE="G:\lasso.txt",EXIST=ALIVE)


    IF(ALIVE) THEN
       DO I=1,67
         READ(10,*) X(I,:),Y(I)
       END DO
    ELSE
       WRITE(*,*) "ERROR HAPPENS"
    END IF



    !REAL,EXTERNAL::GAM  WHEN FUNCTION IS INCLUDED IN A MODULE,
    !IT'S NOT NECESSARY TO DECLARE THIS FUNCTION IN EXTERNAL FORM



    DO WHILE(.TRUE.)
        GRA=-2*MATMUL(TRANSPOSE(X),Y-MATMUL(X,BETA))
        D=-BETA


        DO I=1,8
           WRITE(*,*) D(I)
        END DO

        DO I=1,DIM2
            WRITE(*,*) I
            IF( ABS(BETA(I)-GRA(I))>LAMBDA) THEN
                  D(I)=-(GRA(I)-SIGN(LAMBDA,GRA(I)-BETA(I)))
            END IF

        END DO


        LD=SQRT(SUM(D**2))


        IF(LD.LT.0.01) EXIT
        PHO=1/LD
        K=0.0;ALPHA0=0.9

        DO WHILE(.TRUE.)
            ALPHA=PHO*ALPHA0**K
            IF(GAM(BETA+ALPHA*D).LT.GAM(BETA)) EXIT
            K=K+1
        END DO

        BETA=BETA+ALPHA*D


    END DO




    stop
end program main


VAR.F90 !模块

MODULE  VAR
  IMPLICIT NONE
  INTEGER,PARAMETER::DIM1=67,DIM2=8
  REAL::X(DIM1,DIM2),Y(DIM1),BETA(DIM2),LAMBDA
  CONTAINS
     REAL FUNCTION GAM(BETA2)
       IMPLICIT NONE
       REAL::BETA2(DIM2)
       GAM=SUM((Y-MATMUL(X,BETA2))**2)+&
                 &LAMBDA*SUM(ABS(BETA2))
       RETURN
     END FUNCTION
END MODULE


这个程序是我自己写的一个算法的实现,具体含义不用去管它,我就是对程序中的几个问题不明白,这主要在中间的那个DO WHILE循环中:
1:BETA是个8维向量,已经初化到0。因此在第一次执行DO WHILE循环时,D中各元素应该全是0;其次,在接下来DO循环中的WRITE语句中,应该分别输出12345678(DIM2=8)。所以在执行程序时,结果应为:00000000(8个0)12345678……(忽略输出格式)。但在我的机子了跑的结果却是12345678……。

2:将3行D的输出程序简化为WRITE(*,*) D。理论上更改之后的输出应该与之前的输出一致,但跑出来的结果却是:345678……。

想了一天,不得其解,求高人指点。

回复列表 (共39个回复)

沙发

我用cvf运行了一下. 
1.首先那个什么lasso.txt文件打开的不合理, 既然后面又INQUIRE函数, 为什么要在前面就OPEN呢? 开了可能就创建了. 接着竟然没有CLOSE...

2.MATMUL最好不要嵌套使用, 至于原因我也不是很清楚. 雪球兄有个解释, 有兴趣请教一下他.

3.结果. 这是你关注的. 我这边cvf6.6c运行出来就是8个0之后12345678 , 改成write(*,*) D之后结果还是一样.(我把你读文件部分屏蔽掉了) 所以我想问, 你不会是用powstation作为编译器吧?

板凳

[quote]我用cvf运行了一下. 
1.首先那个什么lasso.txt文件打开的不合理, 既然后面又INQUIRE函数, 为什么要在前面就OPEN呢? 开了可能就创建了. 接着竟然没有CLOSE...

2.MATMUL最好不要嵌套使用, 至于原因我也不是很清楚. 雪球兄有个解释, 有兴趣请教一下他.

3.结果. 这是你关注的. 我这边cvf6.6c运行出来就是8个0之后12345678 , 改成write(*,*) D之后结果还是一样.(我把你读文件部分屏蔽掉了) 所以我想问, 你不会是用powstation作为编译器吧?[/quote]

1:因为我刚看了文件打开那一章,所以就照葫芦画瓢,是应该先INQUIRE。
2:本例中MAUMUL的嵌套应该没什么影响吧。
3:用的INTEL FORTRAN 11。关于结果我也很郁闷,又无法解释。我做了很多尝试,多加或少加一个WRITE函数有时结果就不同。
还有就是DO WHILE那个循环退出条件,0.01本来是控制精度的,但我将它改成0.001就算不出来(这个算法我是在其它语言实现过的,过程没问题,因为刚学的FORTRAN所以想用FORTRAN写一个),我也不知道为什么。

我将LASSO这个文件传一下吧,希望能帮我找出问题。

3 楼

MAUMUL的嵌套你有兴趣可以测试一下. 我自己碰到过一次, 把他们都改了结果就对了. 我师弟也说有问题. 之所以没深究他是因为我已经不再使用matmul了.

你不妨引入一个几率Do循环的记录变量考察究竟循环到第几次, 第几次的write是什么. 那个D输出按理来说就是排列顺序不同而已, 内容应该一样. 有必要的话你可以帖上来.

刚才简单运行了一下已经把工程都删了, 因为不想涉及到里面的算法. 要么楼主你把以上一些运行信息发上来或者看看论坛那位朋友有时间去帮忙找找原因.

4 楼

如你所说,我又加了一个记录DO WHILE循环次数的变量J,然后每次同时输出J和D。正常的输出应该是J从0开始,然后依次增加。但实际却是从179开始,我想这就是症结,却不知为什么?

修改后的主程序:
program main
    USE VAR
    IMPLICIT NONE
    ! DATA BETA /8*0/ DATA initializaion is not allowed
    ! When the variable is defined in a module,So:
    INTEGER::I,J! cycle index
    REAL::GRA(DIM2)!GRADIENT
    REAL::D(DIM2) !for use of d=-b
    REAL::LD,PHO
    REAL::K,ALPHA0,ALPHA

    LOGICAL::ALIVE
    LAMBDA=REAL(2)
    J=0

    BETA=(/(0.0,I=1,8)/)
    OPEN(10,FILE="G:\lasso.txt") !write(t(matrix(temp,67,9)),"G:\\lasso.txt",ncolumns=9)
    INQUIRE(FILE="G:\lasso.txt",EXIST=ALIVE)


    IF(ALIVE) THEN
       DO I=1,67
         READ(10,*) X(I,:),Y(I)
       END DO
    ELSE
       WRITE(*,*) "ERROR HAPPENS"
    END IF



    !REAL,EXTERNAL::GAM  WHEN FUNCTION IS INCLUDED IN A MODULE,
    !IT'S NOT NECESSARY TO DECLARE THIS FUNCTION IN EXTERNAL FORM



    DO WHILE(.TRUE.)
        GRA=-2*MATMUL(TRANSPOSE(X),Y-MATMUL(X,BETA))
        D=-BETA

        WRITE(*,*) J,D




        DO I=1,DIM2

            IF( ABS(BETA(I)-GRA(I))>LAMBDA) THEN
                  D(I)=-(GRA(I)-SIGN(LAMBDA,GRA(I)-BETA(I)))
            END IF

        END DO


        LD=SQRT(SUM(D**2))


        IF(LD.LT.0.01) EXIT
        PHO=1/LD
        K=0.0;ALPHA0=0.9

        DO WHILE(.TRUE.)
            ALPHA=PHO*ALPHA0**K
            IF(GAM(BETA+ALPHA*D).LT.GAM(BETA)) EXIT
            K=K+1
        END DO

        BETA=BETA+ALPHA*D

        J=J+1
    END DO




    stop
end program main

5 楼


这是运行结果:
         179 -0.5487449     -0.2317974      8.2968913E-02 -0.1592907
 -0.2238190      0.1426525      5.9767743E-04 -0.1660929
         180 -0.5483247     -0.2316105      8.3178721E-02 -0.1592584
 -0.2234282      0.1430828      5.9464184E-04 -0.1657131
         181 -0.5487418     -0.2317986      8.2968533E-02 -0.1592908
 -0.2238192      0.1426447      5.9162721E-04 -0.1660864
         182 -0.5483221     -0.2316116      8.3178483E-02 -0.1592585
 -0.2234285      0.1430760      5.8863661E-04 -0.1657071
         183 -0.5487396     -0.2317998      8.2968406E-02 -0.1592909
 -0.2238196      0.1426387      5.8563834E-04 -0.1660808
         184 -0.5483202     -0.2316128      8.3178453E-02 -0.1592585
 -0.2234292      0.1430707      5.8269204E-04 -0.1657018
         185 -0.5487380     -0.2318009      8.2968444E-02 -0.1592910
 -0.2238204      0.1426340      5.7971006E-04 -0.1660758
         186 -0.5483189     -0.2316139      8.3178565E-02 -0.1592586
 -0.2234300      0.1430665      5.7680707E-04 -0.1656970
         187 -0.5487369     -0.2318021      8.2968622E-02 -0.1592910
 -0.2238213      0.1426302      5.7384110E-04 -0.1660712
         188 -0.5483178     -0.2316151      8.3178803E-02 -0.1592585
 -0.2234311      0.1430631      5.7098060E-04 -0.1656927
         189 -0.5487360     -0.2318032      8.2968891E-02 -0.1592909
 -0.2238224      0.1426271      5.6803093E-04 -0.1660670
         190 -0.5483172     -0.2316162      8.3179086E-02 -0.1592585
 -0.2234322      0.1430602      5.6521193E-04 -0.1656886
         191 -0.5487355     -0.2318043      8.2969211E-02 -0.1592909
 -0.2238236      0.1426245      5.6227844E-04 -0.1660631
         192 -0.5483167     -0.2316173      8.3179452E-02 -0.1592585
 -0.2234334      0.1430578      5.5950054E-04 -0.1656847
         193 -0.5486933     -0.2317866      8.2990572E-02 -0.1592876
 -0.2237857      0.1426658      5.5687496E-04 -0.1660218
         194 -0.5483541     -0.2316352      8.3160900E-02 -0.1592613
 -0.2234697      0.1430167      5.5412110E-04 -0.1657151
         195 -0.5486930     -0.2317877      8.2990982E-02 -0.1592875
 -0.2237869      0.1426638      5.5123313E-04 -0.1660182
         196 -0.5483539     -0.2316363      8.3161317E-02 -0.1592613
 -0.2234710      0.1430148      5.4852164E-04 -0.1657116
         197 -0.5486928     -0.2317888      8.2991421E-02 -0.1592875
 -0.2237882      0.1426620      5.4564694E-04 -0.1660147
         198 -0.5483160     -0.2316206      8.3180673E-02 -0.1592583
 -0.2234372      0.1430521      5.4268050E-04 -0.1656740
         199 -0.5486926     -0.2317899      8.2991831E-02 -0.1592874
 -0.2237895      0.1426603      5.4009841E-04 -0.1660113
         200 -0.5483159     -0.2316216      8.3181120E-02 -0.1592582
 -0.2234385      0.1430504      5.3717737E-04 -0.1656707
         201 -0.5486926     -0.2317909      8.2992285E-02 -0.1592873
 -0.2237908      0.1426587      5.3460972E-04 -0.1660079
        以下略去。。。
      
Process returned 0 (0x0)   execution time : 0.558 s
Press any key to continue.

6 楼

什么编译器?我用gfortran无法重现这个问题。

7 楼

在write后面加个pause, 怎么看也不应该j=179开始...

楼主说他用的是ivf11

8 楼

是够诡异吧,我用的是CB+IVF11。就是因为这个问题,所以之前我开了一个帖子“诡异的输出”,不过那时不知道症结在哪,经过yeg001的提醒所以设了一个计数器,果然最后的结果有问题。

9 楼

更加让我不解的是,如果单单只是WRITE(*,*) J,结果又会不一样:33,34,35,36……

10 楼


加了PAUSE之后一切都正常,但去掉后,输出就走神

我来回复

您尚未登录,请登录后再回复。点此登录或注册