回 帖 发 新 帖 刷新版面

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

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个回复)

11 楼

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


你将中间一段“        IF(LD.LT.0.01) EXIT”改成   “IF(LD.LT.0.001) EXIT”试试,看能不能跑出结果。在我这是跑不出结果

12 楼

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


你将中间一段“        IF(LD.LT.0.01) EXIT”改成   “IF(LD.LT.0.001) EXIT”试试,看能不能跑出结果。在我这是跑不出结果[/quote]
我不知道你要得到什么结果
我这里J就是从0开始的

13 楼

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

[/quote]
是么,你那个帖子也并不诡异,看我回复。

14 楼

我还专门去找了ivf12,和gfortran结果一致,J都是从0开始,不知道你说的诡异点在哪?

15 楼


正常应该是J从0开始,紧接跟着D(开始时应该全是0),然后J=1,新的D。
但我的J却是从179开始的。

如果将退出条件改为IF(LD.LT.0.001) EXIT,我这边跑不出结果,也就是说,最后根本算不出来,循环也退不出来。

16 楼

当然出不来了

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

这个是死循环

17 楼


那个不是有EXIT 条件么

18 楼

但你这个是内层循环,一次跳出去,下次就又进去了,最后时这个条件始终不满足,就无法跳出了

19 楼

外层循环我也有 IF(LD.LT.0.01) EXIT这个跳出条件啊

20 楼

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

我来回复

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