主题:怎么退出循环?exit?goto?
tianhy2010
[专家分:60] 发布于 2010-08-27 09:42:00
我有个程序段,算了好久了 ,发现下面这个地方缺东西了,没有退出循环就进行下一次运算了。
ea=0.0
eb=0.0
ec=0.0
ed=0.0
do p=1,450000
do i=1,4*m*n-1
if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) then
do temp=1,i
do j=i+1,4*m*n
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
conr=2*pi*aimag(conduc)/S
end if
end do
end do
eigenvalue是矩阵特征值,Ef是能量。
上面这个片段好像第一次是ea,eb,ec,ed都从0开始,i=1,开始第一次运算,内部循环以后给他们赋值,然后第二次运算就从这个值开始,不是从0开始了吧?我想仍然让它从0开始,在哪个地方加exit?或者goto语句呢?在end if前面加exit到底是退出if语句还是整个循环啊?
关于运算大家看下这样行不?我想把每个i得到的conduc都放在conr里,会不会后面的数据把前面的数据覆盖掉?
回复列表 (共25个回复)
11 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 14:11:00
您的意思是,算完一个Ef(p)得到conduc,然后得到一个conr,退出这个Ef(p),接着让conduc=0.0,进行下一个Ef(p)计算,每次算一个新的Ef(p)都让conduc从0开始啦。
您看这样行不?我在程序前面加上conduc=0.0,然后再end if后面加上exit,算完一个Ef(p)就退出,然后算下一个Ef(p),而且conduc=0.0。
conduc=0.0
do p=1,450000
do i=1,4*m*n-1
if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) then
do temp=1,i
do j=i+1,4*m*n
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
conr=2*pi*aimag(conduc)/S
end if
exit !退出循环,让conduc=0.0,计算下一个Ef(p)
end do
end do
12 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 14:21:00
[quote]您的意思是,算完一个Ef(p)得到conduc,然后得到一个conr,退出这个Ef(p),接着让conduc=0.0,进行下一个Ef(p)计算,每次算一个新的Ef(p)都让conduc从0开始啦。
您看这样行不?我在程序前面加上conduc=0.0,然后再end if后面加上exit,算完一个Ef(p)就退出,然后算下一个Ef(p),而且conduc=0.0。
conduc=0.0
do p=1,450000
do i=1,4*m*n-1
if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) then
do temp=1,i
do j=i+1,4*m*n
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
conr=2*pi*aimag(conduc)/S
end if
exit !退出循环,让conduc=0.0,计算下一个Ef(p)
end do
end do
[/quote]
exit是退出本循环体!cycle是退出本次循环,不再执行cycle后面的语句。问题是先要搞清楚程序!再看需要不需要exit或者cycle!
conduc到底要累加什么?你的程序是对每个i,满足条件的p都进行了累加,不光这样,当i变的时候,conduc在原来的基础上还在累加!!
这是我困惑的地方!conduc累加的是啥?卷积么?哎,晕!
13 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 15:13:00
呵呵,多谢了。我举个例子吧。好像里面还有个计数关系,开始时应该让conr=0.0。
i=1,2,3时,eigenvalue(i)和(eigenvalue(i+1)之间没有Ef(p),不计算conduc
i=4时,在eigenvalue(4)和(eigenvalue(5)之间有两个Ef(p),分别是Ef(78)和Ef(79)。
p=78,执行下面的两个循环,将得到的结果赋给conduc,而且进行求和操作,并将最后得到的conduc带入conr进行计算,得到p=78时的conr(78),循环结束让conduc=0.0。
do temp=1,i
do j=i+1,4*m*n !4以后的所有数,一直到4mn
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
conr(78)=2*pi*aimag(conduc)/S
p=78计算完成,再计算p=79,这时候要让conduc=0.0开始计算,再执行相同的循环,得到p=79的conr,其实两个是相同的,把它们单独写出来,而不是将两个conr求和相加。也就是说,每个Ef(p)对应一个自己的conr(p),计算每个Ef(p)时,conduc的初值都为0,conr(p)的初值也为0。
这样表达可以了吗?呵呵,真的很感谢您
14 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 15:20:00
我想着计算完一个i对应的p之后,再算下一个i对应的p,每个p都有自己的conr(p),再进行第二个p的计算的时候,让conduc和conr都为0。进行完一个p的计算怎么退出本次循环,进行第二个p的计算呢?而且读取初值conduc和conr都为0?该加cycle吧?
15 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 15:52:00
do i=1,4*m*n-1
do p=1,450000
conduc=0.0
if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) then
do temp=1,i
do j=i+1,4*m*n
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
conr(p)=2*pi*aimag(conduc)/S
end if
end do
end do
看看这样行不行?因为eigenvalue(i)与Ef(p)都是单调变化的,因此每个i找到的p都是不同的,所有i循环完,每个p应该最多出现一次,这样,把conr定义成一维数组用于存放每个p对应的conduc值(2*pi*aimag(conduc)/S)。
16 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 16:01:00
太感激了!!谢谢老师
17 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 16:35:00
其实,你是要对每个Ef(p)找对应的i,基于eigenvalue(i)和Ef(p)都是单调递增,每个Ef(p)只能找到一个i,而且p增加的时候,i也必然增加!所以这样写或许效率更高一些!
q=1
do p=1,450000
conduc=0.0
do i=q,4*m*n-1
if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) then
q=i !下一次i的循环从q开始,因为下个Ef(p)值找到的i肯定大于q了!
do temp=1,i
do j=i+1,4*m*n
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
exit !找到i就不再循环下去了!
end if
end do
conr(p)=2*pi*aimag(conduc)/S
end do
18 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 19:11:00
太经典啊!!!!好人啊!!上帝爱我!!!!
19 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 21:27:00
我好好想了下,在我得到的数据里,某些eigenvalue(i)和eigenvalue(i+1)之间没有Ef(p),而另外的两个特征值之间又有好几个Ef(p),我要把这好几个Ef(p)得到的conduc加在一起带入conr中计算。为了使效率更高些,我改了下,请老师指正:
q=1
do p=q,450000
conduc=0.0
do i=1,4*m*n-1
if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) then
q=p+1 !下一次p的循环从p+1开始,因为下个Ef(p)值找到的i也可能与前一个i相同!
do temp=1,i
do j=i+1,4*m*n
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
conr(i)=2*pi*aimag(conduc)/S !将p改为i,说明是在这个特征值上的总和,因为这个特征值上可能会有几个Ef(p),要把他们的conduc和求出来放在conr中
cycle !找到i就不再循环下去了!
end if
end do
end do
就是有个地方还不甚清楚。如果在eigenvalue(4)和eigenvalue(5)之间有2个Ef(p),分别是Ef(35),Ef(36),p=35,发现满足if语句,q=p+1=36,计算p=35得到的conduc值,然后带入到conr中,退出本次循环,进行下次循环;p=36,conduc=0.0(而不是保持p=35得到的值),发现还满足if语句,在算一次,又得到p=36的conduc和conr,而没有将eigenvalue(4)和eigenvalue(5)之间的conduc相加带入conr中进行计算。
这个地方该从哪里退出本次循环呢?
20 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 22:48:00
你看这样是不是符合你的要求,仔细研究了一下exit和cycle的区别,才发现这里需用exit才能提高效率!
q=1
do i=1,4*m*n-1
conduc=0.0
k=0
do p=q,450000
if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) then
q=p+1
k=k+1 !对于i,能满足条件的Ef(p)的个数!
do temp=1,i
do j=i+1,4*m*n
ea=matmul(traneigv(temp,:),hx)
ec=matmul(traneigv(temp,:),hy)
eb=matmul(traneigv(j,:),hx)
ed=matmul(traneigv(j,:),hy)
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
end do
end do
else
if (k>0) then
exit !k>0 有Ef(p)满足过条件,突然不满足了就退出(再找也是白找);否则一直循环到底(k=0)!
endif
end if
end do
conr(i)=2*pi*aimag(conduc)/S
end do
我来回复