主题:各位帮忙看看我的问题!
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个回复)
31 楼
dongyuanxun [专家分:7180] 发布于 2011-04-28 14:47:00
上面跟你说了
你的LD永远大于0.01
最后显示的值是LD=6.5784E-02
然后就进入
DO WHILE(.TRUE.)
ALPHA=PHO*ALPHA0**K
IF(GAM(BETA+ALPHA*D).LT.GAM(BETA)) EXIT
K=K+1
END DO
这个循环出不来
32 楼
llbbhq [专家分:0] 发布于 2011-04-28 14:53:00
[quote]上面跟你说了
你的LD永远大于0.01
最后显示的值是LD=6.5784E-02
然后就进入
DO WHILE(.TRUE.)
ALPHA=PHO*ALPHA0**K
IF(GAM(BETA+ALPHA*D).LT.GAM(BETA)) EXIT
K=K+1
END DO
这个循环出不来
[/quote]
我的结果是:第326次循环,LD=5.0026015E-03。
DO WHILE 循环程序:
DO WHILE(.TRUE.)
GRA=-2*MATMUL(TRANSPOSE(X),Y-MATMUL(X,BETA))
D=-BETA
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))
WRITE(*,*) J, LD
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
33 楼
dongyuanxun [专家分:7180] 发布于 2011-04-28 15:00:00
我这里326次是7.45E-02
34 楼
cgl_lgs [专家分:21040] 发布于 2011-04-28 15:01:00
[quote][quote][quote]问题是我的滚动条拉到最上也只有179,也不是0[/quote]
你的数据那么多,肯定不会滚到0
缓冲区是一定的,不能无限扩展
cmd鼠标右键点击属性
把缓冲区大小和数量都调到最大吧[/quote]怎么改缓冲区? 我运行CMD后,鼠标右键并没属性一项啊,只有什么标记、滚动、查找什么的[/quote]
在窗口左上角左键单击就行了,改“默认”不要改“属性”。
改完后关了重运行看看:)
35 楼
llbbhq [专家分:0] 发布于 2011-04-28 15:01:00
[quote]我这里326次是7.45E-02
[/quote]
这是为什么,我在第326次就直接退出循环了。是不是变量的精度问题
36 楼
llbbhq [专家分:0] 发布于 2011-04-28 15:06:00
[quote][quote][quote][quote]问题是我的滚动条拉到最上也只有179,也不是0[/quote]
你的数据那么多,肯定不会滚到0
缓冲区是一定的,不能无限扩展
cmd鼠标右键点击属性
把缓冲区大小和数量都调到最大吧[/quote]怎么改缓冲区? 我运行CMD后,鼠标右键并没属性一项啊,只有什么标记、滚动、查找什么的[/quote]
在窗口左上角左键单击就行了,改“默认”不要改“属性”。
改完后关了重运行看看:)[/quote]
还是不行,我把缓冲区大小改为999,缓冲区数量改为999,问题依旧
37 楼
llbbhq [专家分:0] 发布于 2011-04-28 15:15:00
[quote][quote][quote][quote][quote]问题是我的滚动条拉到最上也只有179,也不是0[/quote]
你的数据那么多,肯定不会滚到0
缓冲区是一定的,不能无限扩展
cmd鼠标右键点击属性
把缓冲区大小和数量都调到最大吧[/quote]怎么改缓冲区? 我运行CMD后,鼠标右键并没属性一项啊,只有什么标记、滚动、查找什么的[/quote]
在窗口左上角左键单击就行了,改“默认”不要改“属性”。
改完后关了重运行看看:)[/quote]
还是不行,我把缓冲区大小改为999,缓冲区数量改为999,问题依旧[/quote]
行了,果然是这个问题。开始我改的是选项中的缓冲区,后来将布局中的缓冲区大小与窗口大小都改了一下。这个问题算是解决了。这个问题太重要了。我第一次发现这个是因为发现循环退不出来,所以就一直找问题,所以就想把每步的结果输出来看看,才发现这个。若不是这样,之后的DEBUG可能就会很辛苦了。万分感谢
38 楼
yeg001 [专家分:14390] 发布于 2011-04-28 16:01:00
如果你嫌显示的被刷掉可以输出到文件, 然后看文件的.
那些多少次退出, 能否退出的应该由你的算法保证. 你的代码不长应该算法也不复杂. 而且你有其它语言的基础, 问题应该很好找啊.
39 楼
llbbhq [专家分:0] 发布于 2011-04-28 17:32:00
[quote]如果你嫌显示的被刷掉可以输出到文件, 然后看文件的.
那些多少次退出, 能否退出的应该由你的算法保证. 你的代码不长应该算法也不复杂. 而且你有其它语言的基础, 问题应该很好找啊.[/quote]
初步怀疑是MATMUL函数的问题,因为在FORTRAN和我之前那个程序对比时发现,它俩相乘的结果都是不一样的。
我来回复