回 帖 发 新 帖 刷新版面

主题:怎么退出循环?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个回复)

11 楼

您的意思是,算完一个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 楼

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

呵呵,多谢了。我举个例子吧。好像里面还有个计数关系,开始时应该让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 楼

我想着计算完一个i对应的p之后,再算下一个i对应的p,每个p都有自己的conr(p),再进行第二个p的计算的时候,让conduc和conr都为0。进行完一个p的计算怎么退出本次循环,进行第二个p的计算呢?而且读取初值conduc和conr都为0?该加cycle吧?

15 楼


  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 楼

太感激了!!谢谢老师

17 楼

其实,你是要对每个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 楼

太经典啊!!!!好人啊!!上帝爱我!!!!

19 楼

我好好想了下,在我得到的数据里,某些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 楼

你看这样是不是符合你的要求,仔细研究了一下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

我来回复

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