主题:为何计算结果不一样
lqmj
[专家分:40] 发布于 2011-05-27 17:15:00
以下是程序中的一段
sty = 0.0d0
gty = 0.d0
gts = 0.d0
do i = 1,n
s(i) = xnew(i) - x(i)
y(i) = gnew(i) - g(i)
sts = sts + s(i) ** 2
sty = sty + s(i) * y(i)
gty = gty + gnew(i)*y(i)
gts = gts + gnew(i)*s(i)
x(i) = xnew(i)
g(i) = gnew(i)
end do
* --------------------------------- Theta Computation (spectral)
if ( sty .le. 0.0d0 ) then
theta = 1.0d+10
else
theta = min( 1.0d+10, max( 1.0d-10, sts / sty ) )
end if
* --------------------------------- beta Computation
a = 0.0d0
do i = 1,n
a = a + ( theta * y(i) - s(i) ) * g(i)
end do
b = sty
if ( b .ne. 0.0d0 ) then
beta = a / b
els
beta = 0.0d0
end if
*-----------------------
我的问题是:奇怪的是我把如下一段程序:
a = 0.0d0
do i = 1,n
a = a + ( theta * y(i) - s(i) ) * g(i)
end do
改为 a = theta*gty-gts时,计算结果竟然不一样,真不知为啥,感谢各位高手能给予指点
回复列表 (共17个回复)
沙发
yeg001 [专家分:14390] 发布于 2011-05-27 20:17:00
请问你的变量gnew初始化在哪里?
板凳
yeg001 [专家分:14390] 发布于 2011-05-27 20:23:00
说白了
s(i) = xnew(i) - x(i)
[color=0000FF]y(i)[/color] = gnew(i) - [color=FF0000]g(i)[/color]
sts = sts + s(i) ** 2
sty = sty + s(i) * y(i)
gty = gty + gnew(i)*[color=0000FF]y(i)[/color]
gts = gts + gnew(i)*s(i)
x(i) = xnew(i)
[color=00FF00]g(i)[/color] = gnew(i)
前面的gty是用原数据g获得的. 而你后面计算里面的g是用这里更新之后的g获得的. 能否相同却决于这个过程有没有更改了数据. gts同样道理.
3 楼
lqmj [专家分:40] 发布于 2011-05-28 00:13:00
谢谢老师的帮助,但我还是不明白啊。
1 gnew的值由call一子程序得到,我想在此处不用初始化吧,不知是否说的对。
2 前面的gty = gty + gnew(i)*y(i),所以前面的gty当然是由更新之后的g获得,我后面计算里面的g也是用更新之后的g获得的。
4 楼
yeg001 [专家分:14390] 发布于 2011-05-28 09:42:00
gnew的值由call子程序得到就已经是赋值过了.
gty=gty + gnew(i)*y(i) 的y(i)是由之前得到g(i)得到的, 也就是gty依赖原来的g, 但循环到最后一行
g(i) = gnew(i) 这里的g(i)被更新了.
那么最后取代的两行代码
a= a+(theta*y(i) - s(i)) * g(i) 与 a = theta*gty-gts
前者的循环求和是依赖更新后的g, 而后者使用的gty是依赖更新前的g. 但你说结果不同似乎这么只要gnew跟g不同就很有可能使得结果不同.
gts同样道理.
5 楼
lqmj [专家分:40] 发布于 2011-06-02 17:04:00
我咋还不明白啊,都不好意思再发帖问了。但不弄明白不行啊,只好再次硬着头皮发帖问问:
gty=gty + gnew(i)*y(i)(1) , g(i) = gnew(i) 这里的g(i)被更新了.
对比最后取代的代码
a= a+(theta*y(i) - s(i)) * g(i) (2)
可以看到(1)中的gnew(i)与(2)中的g(i)相等,(1)中的y(i)与(2)中的y(i)相等因为从(1)运行到(2)一直没有重新赋值,所以a= a+(theta*y(i) - s(i)) * g(i) 与 a = theta*gty-gts的值应该一样啊
6 楼
lqmj [专家分:40] 发布于 2011-06-02 18:01:00
do i =1,n
a= a+(theta*y(i) - s(i)) * g(i)
enddo
与 a = theta*gty-gts的值应该一样啊
7 楼
lqmj [专家分:40] 发布于 2011-06-02 18:32:00
从数学推理上他们是相等的,也许是计算顺序不一样致使两种算法A的值有误差而导致最终结果不一样,对于有些问题结果相差不大,对于有些问题差的很远
8 楼
dongyuanxun [专家分:7180] 发布于 2011-06-02 18:47:00
记得某人数学推理C语言
a=a+1
可得,0=1
9 楼
yeg001 [专家分:14390] 发布于 2011-06-02 21:01:00
[quote]我咋还不明白啊,都不好意思再发帖问了。但不弄明白不行啊,只好再次硬着头皮发帖问问:
gty=gty + gnew(i)*y(i)(1) , g(i) = gnew(i) 这里的g(i)被更新了.
对比最后取代的代码
a= a+(theta*y(i) - s(i)) * g(i) (2)
可以看到(1)中的gnew(i)与(2)中的g(i)相等,(1)中的y(i)与(2)中的y(i)相等因为从(1)运行到(2)一直没有重新赋值,所以a= a+(theta*y(i) - s(i)) * g(i) 与 a = theta*gty-gts的值应该一样啊
[/quote]
时隔几天, 我也要重新看这个问题才想起是什么回事了. 所以如果觉得这个问题应该解决还是尽早, 趁还有热度.
我再认真看了一下代码, 你的说法应该是对的. x(i) = xnew(i), g(i) = gnew(i)这步其实可以不要, 而后面的g(i)用gnew(i)变量就可以了, 而我错误地认为g被更新过gty就不能再代表(2)中的求和了.
这样看来你的分析是对的. 这样的话就要看看你输入的数据是什么,而且两种算法算出来结果相差多少? 可否把输入数据跟结果帖出来?
10 楼
lqmj [专家分:40] 发布于 2011-06-02 23:07:00
a 的计算采用循环求和时,计算结果如下:
1 SCG Algorithm:Extended Freudenstein & Roth Function
theta spectral. betatype = 1 (Scaled Perry - Birgin & Martinez)
n iter irs fgcnt lscnt time(c) fxnew gnorm
------------------------------------------------------------------------------------
1000 25 2 397 24 4 0.2449212683962E+05 0.7981417847247E-06
2000 12 1 26 12 0 0.4898425367924E+05 0.4442470205321E-07
3000 75 4 1783 72 47 0.7347638051886E+05 0.9544459780518E-06
4000 72 1 1535 70 55 0.9796850735848E+05 0.9934647556328E-06
5000 114 1 2993 114 128 0.1224606341981E+06 0.9957567321459E-06
6000 109 1 2833 108 145 0.1469527610377E+06 0.9657832793676E-06
7000 12 1 27 12 3 0.1714448878773E+06 0.1016856630738E-07
8000 40 1 772 40 55 0.1959370147169E+06 0.9101439495637E-06
9000 33 2 450 32 36 0.2204291415566E+06 0.9513035250659E-06
10000 59 1 1360 59 119 0.2449212683962E+06 0.6153381801946E-06
------------------------------------------------------------------------------------
TOTAL 551 15 12176 543 5.92 (seconds) proc= 2.72%
我来回复