主题:各位帮忙看看我的问题!
llbbhq
[专家分:0] 发布于 2011-04-27 18:50:00
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……。
想了一天,不得其解,求高人指点。
最后更新于:2011-04-27 22:57:00
回复列表 (共39个回复)
沙发
yeg001 [专家分:14390] 发布于 2011-04-27 20:40:00
我用cvf运行了一下.
1.首先那个什么lasso.txt文件打开的不合理, 既然后面又INQUIRE函数, 为什么要在前面就OPEN呢? 开了可能就创建了. 接着竟然没有CLOSE...
2.MATMUL最好不要嵌套使用, 至于原因我也不是很清楚. 雪球兄有个解释, 有兴趣请教一下他.
3.结果. 这是你关注的. 我这边cvf6.6c运行出来就是8个0之后12345678 , 改成write(*,*) D之后结果还是一样.(我把你读文件部分屏蔽掉了) 所以我想问, 你不会是用powstation作为编译器吧?
板凳
llbbhq [专家分:0] 发布于 2011-04-27 22:56:00
[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 楼
yeg001 [专家分:14390] 发布于 2011-04-28 00:00:00
MAUMUL的嵌套你有兴趣可以测试一下. 我自己碰到过一次, 把他们都改了结果就对了. 我师弟也说有问题. 之所以没深究他是因为我已经不再使用matmul了.
你不妨引入一个几率Do循环的记录变量考察究竟循环到第几次, 第几次的write是什么. 那个D输出按理来说就是排列顺序不同而已, 内容应该一样. 有必要的话你可以帖上来.
刚才简单运行了一下已经把工程都删了, 因为不想涉及到里面的算法. 要么楼主你把以上一些运行信息发上来或者看看论坛那位朋友有时间去帮忙找找原因.
4 楼
llbbhq [专家分:0] 发布于 2011-04-28 10:34:00
如你所说,我又加了一个记录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 楼
llbbhq [专家分:0] 发布于 2011-04-28 10:36:00
这是运行结果:
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 楼
dongyuanxun [专家分:7180] 发布于 2011-04-28 11:00:00
什么编译器?我用gfortran无法重现这个问题。
7 楼
yeg001 [专家分:14390] 发布于 2011-04-28 11:49:00
在write后面加个pause, 怎么看也不应该j=179开始...
楼主说他用的是ivf11
8 楼
llbbhq [专家分:0] 发布于 2011-04-28 12:21:00
是够诡异吧,我用的是CB+IVF11。就是因为这个问题,所以之前我开了一个帖子“诡异的输出”,不过那时不知道症结在哪,经过yeg001的提醒所以设了一个计数器,果然最后的结果有问题。
9 楼
llbbhq [专家分:0] 发布于 2011-04-28 12:39:00
更加让我不解的是,如果单单只是WRITE(*,*) J,结果又会不一样:33,34,35,36……
10 楼
llbbhq [专家分:0] 发布于 2011-04-28 12:41:00
加了PAUSE之后一切都正常,但去掉后,输出就走神
我来回复