主题:怎么退出循环?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个回复)
沙发
jstzhurj [专家分:4680] 发布于 2010-08-27 10:46:00
你的eigenvalue(i)随i增加单调递减?每个p能对应一个i?想干什么能再具体点吗?单从程序上看很难明白你想实现什么。
板凳
tianhy2010 [专家分:60] 发布于 2010-08-27 11:18:00
呵呵,多谢提醒啦
!给能量Ef赋值
do i=1,450000
Ef(i)=-2.7+0.0000127*i
end do
!求矩阵H的特征值和特征向量
eigenvalue=eig(h,w=eigenvector)
traneigv=transpose(eigenvector) !求特征向量的转置矩阵
!对特征值进行排序,特征值共有4*m*n个,m,n由外部给出
do j=1,4*n*m-1
p=j
do i=j+1,4*m*n
if(eigenvalue(i)<eigenvalue(p)) p=i
end do
temp=eigenvalue(j)
eigenvalue(j)=eigenvalue(p)
eigenvalue(p)=temp
end do
!求conr
ea=0.0
eb=0.0
ec=0.0
ed=0.0
!hx,hy都是(4*m*n,4*m*n)矩阵
do i=1,4*m*n-1
do p=1,450000
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(i)和eigenvalue(i+1)之间是否存在一个Ef,如果存在,就执行下面的操作,分别给ea,eb,ec,ed赋值取代初始值0,比如,i=1,则看下哪个Ef在eigenvalue(1)和eigenvalue(2)之间,如果没有合适的,就继续i=2,看下哪个Ef在eigenvalue(2)和eigenvalue(3)之间,如果还没有继续找下面的i;如果在i=4的时候,发现有个Ef在eigenvalue(4)和eigenvalue(5)之间,就按照公式给ea,eb,ec,ed赋值。
问题是:如果在i=4发现一个Ef,而且给ea,eb,ec,ed赋值了,到i=8又发现一个Ef满足条件,然后又要给ea,eb,ec,ed赋值,这两次是独立的,后面的值会覆盖掉前面的值吧?
问题2:如果把conr放在end if前面会不会出现这种情况;第二次的结果把第一次的结果覆盖了。把所有的i检查完了之后,conr的结果应该全部记录了吧?还是把conr放在第三个do后面?
3 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 12:20:00
问题1 是的,会覆盖。
问题2 conr每次会被覆盖,我的理解是,你要对每个i都得到一个conr,那应该放在p循环体之外,就是对应每个i,都是对p循环完之后得到一个conr。
另:对于特定的i,conduc对每个满足条件的p进行了累加,对所有的i也进行累加吗?
4 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 13:42:00
你问的很地道,一直见血啊!!我怎么就没想到呢。
问题2 conr每次会被覆盖,我的理解是,你要对每个i都得到一个conr,那应该放在p循环体之外,就是对应每个i,都是对p循环完之后得到一个conr。
另:对于特定的i,conduc对每个满足条件的p进行了累加,对所有的i也进行累加吗?
是这样的:有的eigenvalue(i)和eigenvalue(i+1)之间没有Ef(p),也就是说两者相差很小,差不多1.0e-7误差,两者是相等的啦;但是有的就不同了,两者之间会有0.5这样的差距,在这样的两个特征值之间是有Ef(p)的,而且可能会有好几个,针对每个Ef(p),都得到一个独立的conr,而不是对这个区间满足条件的Ef(p)得到的conr进行相加然后最后求和,也就是每个Ef(p)对应一个独立的conr。
不对每一个i进行累计,各自算各自的,独立出来。
有个地方好像写错了
!求conr
ea=0.0
eb=0.0
ec=0.0
ed=0.0
!hx,hy都是(4*m*n,4*m*n)矩阵
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
在我的程序里,p只是个判断符号,如果满足eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p)) 这个条件,就把矩阵h特征向量的转置拿出来与hx,hy操作。
5 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 13:46:00
这个程序是先找到满足条件if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) 的所有Ef(p)还是先找到一个Ef(p)计算下结果,然后再看下一个Ef(p)是否满足,如果满足就计算,不满足就继续找下去呢?
另外,如果两个特征值之间如果有多个Ef(p),那最后得到的结果肯定对他们求和了,我要是想让它算完一个Ef(p)退出,然后算下一个Ef(p),是否在end if前面加exit?或者在哪里加呢?或者goto语句?
6 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 13:51:00
conduc=conduc+(dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp))
conduc 它把所有的满足条件的dot_product(ea,eigenvector(:,j))*dot_product(ed,eigenvector(:,temp)累加了!我没有说conr累加!
7 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 13:55:00
是啊,我写错了,呵呵,该在那里加个退出语句呢?让它算完一个Ef(p)的conduc就把结果传给conr进行计算,然后再算下一个Ef(p),而不是把满足((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) 的所有Ef(p)进行求和?
8 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 13:55:00
[quote]这个程序是先找到满足条件if((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) 的所有Ef(p)还是先找到一个Ef(p)计算下结果,然后再看下一个Ef(p)是否满足,如果满足就计算,不满足就继续找下去呢?
另外,如果两个特征值之间如果有多个Ef(p),那最后得到的结果肯定对他们求和了,我要是想让它算完一个Ef(p)退出,然后算下一个Ef(p),是否在end if前面加exit?或者在哪里加呢?或者goto语句?[/quote]
绕口令啊?!!!
9 楼
tianhy2010 [专家分:60] 发布于 2010-08-27 13:59:00
哈哈。
是啊,我写错了,呵呵,该在那里加个退出语句呢?让它算完一个Ef(p)的conduc就把结果传给conr进行计算,然后再算下一个Ef(p),而不是把满足((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) 的所有Ef(p)进行求和?
把exit加在end if前面行吗?对这个词的使用有些模糊
10 楼
jstzhurj [专家分:4680] 发布于 2010-08-27 14:00:00
[quote]是啊,我写错了,呵呵,该在那里加个退出语句呢?让它算完一个Ef(p)的conduc就把结果传给conr进行计算,然后再算下一个Ef(p),而不是把满足((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p))) 的所有Ef(p)进行求和?[/quote]
conduc何时清零?一直累加下去?思路怎么不清晰呢?
我来回复