回 帖 发 新 帖 刷新版面

主题:怎么退出循环?exit?goto?

我有个程序段,算了好久了 ,发现下面这个地方缺东西了,没有退出循环就进行下一次运算了。
  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个回复)

沙发


你的eigenvalue(i)随i增加单调递减?每个p能对应一个i?想干什么能再具体点吗?单从程序上看很难明白你想实现什么。

板凳

呵呵,多谢提醒啦

!给能量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 楼

问题1 是的,会覆盖。
问题2 conr每次会被覆盖,我的理解是,你要对每个i都得到一个conr,那应该放在p循环体之外,就是对应每个i,都是对p循环完之后得到一个conr。
另:对于特定的i,conduc对每个满足条件的p进行了累加,对所有的i也进行累加吗?

4 楼

你问的很地道,一直见血啊!!我怎么就没想到呢。
    问题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 楼

这个程序是先找到满足条件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 楼


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 楼

是啊,我写错了,呵呵,该在那里加个退出语句呢?让它算完一个Ef(p)的conduc就把结果传给conr进行计算,然后再算下一个Ef(p),而不是把满足((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p)))  的所有Ef(p)进行求和?

8 楼

[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 楼

哈哈。
是啊,我写错了,呵呵,该在那里加个退出语句呢?让它算完一个Ef(p)的conduc就把结果传给conr进行计算,然后再算下一个Ef(p),而不是把满足((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p)))  的所有Ef(p)进行求和?

把exit加在end if前面行吗?对这个词的使用有些模糊

10 楼

[quote]是啊,我写错了,呵呵,该在那里加个退出语句呢?让它算完一个Ef(p)的conduc就把结果传给conr进行计算,然后再算下一个Ef(p),而不是把满足((eigenvalue(i)<=Ef(p)).and.(eigenvalue(i+1)>Ef(p)))  的所有Ef(p)进行求和?[/quote]


conduc何时清零?一直累加下去?思路怎么不清晰呢?

我来回复

您尚未登录,请登录后再回复。点此登录或注册