{"id":1942,"date":"2014-09-01T22:12:38","date_gmt":"2014-09-01T21:12:38","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=1942"},"modified":"2014-09-01T22:12:38","modified_gmt":"2014-09-01T21:12:38","slug":"fortran-progressmeter-nice-code","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=1942","title":{"rendered":"Fortran progressmeter nice code"},"content":{"rendered":"<pre><code>\r\n\r\n\r\n! use modulo to determine when to print progress\r\n! not independet of called algorithm speed\r\n! possible output:\r\n! 0.0  % done\r\n! 0.01 % done\r\n! 0,02 % done\r\n! 0,03 % done\r\n! or only one output\r\n! 80.0 % done\r\n! We can do better!\r\nsubroutine variant1(n)\r\n  implicit none\r\n  integer, intent(in) :: n\r\n  integer :: i\r\n  \r\n  do i=1, n\r\n    if(mod(i, 1000) == 0) write(*,*) 100.0*i\/n, \"% done\"\r\n    \r\n    ! call some algorithm\r\n    ! ...\r\n  end do\r\nend subroutine\r\n\r\n! check in every iteration if progress is 10%, 20% u.s.w.\r\n! pro: independet of called algorithm speed\r\n! contra: more code\r\n! possible output:\r\n! 10 % done\r\n! 20 % done\r\n! 30 % done\r\n! 80 % done\r\n! 90 % done\r\n! We can do better!\r\nsubroutine variant2(n)\r\n  implicit none\r\n  integer, intent(in) :: n\r\n  integer :: i\r\n  real :: percent, thr\r\n  \r\n  thr = 1.0 \/ n * 100.0  \r\n  do i=1, n\r\n    percent = 100.0*i\/n\r\n    if(percent > 10.0 .and. percent < 10.0+thr) write(*,*) \"10 % done\"\r\n    if(percent > 20.0 .and. percent < 20.0+thr) write(*,*) \"20 % done\"\r\n    if(percent > 30.0 .and. percent < 30.0+thr) write(*,*) \"30 % done\"\r\n    if(percent > 40.0 .and. percent < 40.0+thr) write(*,*) \"40 % done\"\r\n    if(percent > 50.0 .and. percent < 50.0+thr) write(*,*) \"50 % done\"\r\n    if(percent > 60.0 .and. percent < 60.0+thr) write(*,*) \"60 % done\"\r\n    if(percent > 70.0 .and. percent < 70.0+thr) write(*,*) \"70 % done\"\r\n    if(percent > 80.0 .and. percent < 80.0+thr) write(*,*) \"80 % done\"\r\n    if(percent > 90.0 .and. percent < 90.0+thr) write(*,*) \"90 % done\"      \r\n    \r\n    ! call some algorithm\r\n    ! ...\r\n  end do\r\nend subroutine\r\n\r\n! recalc threshold in every iteration\r\n! possible output:\r\n! 10 % done\r\n! 20 % done\r\n! 30 % done\r\n! ...\r\n! 90 % done\r\n! almost done!\r\n! we have to avoid duplicate code; copy&paste erros\r\nsubroutine variant3(n)\r\n  implicit none\r\n  integer, intent(in) :: n\r\n  integer :: i\r\n  real :: percent\r\n  integer :: thr\r\n  \r\n  thr = 10\r\n  do i=1, n\r\n    percent = 100.0*i\/n\r\n    if(percent > thr) then\r\n      write(*,*) thr, \"% done\"\r\n      thr = thr +  10\r\n    endif\r\n    \r\n    ! call some algorithm\r\n    ! ...\r\n  end do\r\nend subroutine\r\n\r\n\r\n! to avoid duplicate code and copy&paste errors, we move the code into a class and provide a progress function as interface\r\nmodule ProgressMeterClass\r\n  implicit none\r\n  private\r\n  public :: createProgressMeter\r\n\r\n  type, public :: ProgressMeter\r\n      integer, private :: n\r\n      integer, private :: thr\r\n    contains\r\n\r\n      procedure :: progress\r\n  end type\r\n  \r\n  interface createProgressMeter\r\n    module procedure newProgressMeter\r\n  end interface\r\n\r\n  contains\r\n\r\n  function newProgressMeter(n) result(this)\r\n    implicit none\r\n    type(ProgressMeter) :: this\r\n    integer, intent(in) :: n\r\n\r\n    this%n = n\r\n    this%thr = 10\r\n  end function\r\n\r\n  subroutine progress(this, i)\r\n    implicit none\r\n    class(ProgressMeter), intent(inout) :: this\r\n    integer, intent(in) :: i\r\n\r\n    if(100.0*i\/this%n > this%thr) then\r\n      write(*,*) this%thr, \"% done\"\r\n      this%thr = this%thr + 10\r\n    endif\r\n  end subroutine\r\nend module\r\n\r\n\r\n!> we use OO techniques. The progressmeter code is now in the ProgressMeterClass module.\r\n!> We simply create an object of this type and call progress() on it in every iteration\r\nsubroutine variant4(n)\r\n  use ProgressMeterClass\r\n  implicit none\r\n  integer, intent(in) :: n\r\n  integer :: i\r\n  type(ProgressMeter) :: pm\r\n  \r\n  ! we can pass a step and filehandle variable too\r\n  pm = createProgressMeter(n)\r\n  do i=1, n\r\n    call pm%progress(i)\r\n    \r\n    ! call some algorithm\r\n    ! ...\r\n  end do\r\nend subroutine\r\n\r\nprogram Progressmeter  \r\n  implicit none\r\n  integer :: n\r\n\r\n  n = 10000000\r\n\r\n!   call variant1(n)\r\n!   call variant2(n)  \r\n!   call variant3(n)  \r\n  call variant4(n)  \r\nend program\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>! use modulo to determine when to print progress ! not independet of called algorithm speed ! possible output: ! 0.0 % done ! 0.01 % done ! 0,02 % done ! 0,03 % done ! or only one output ! 80.0 % done ! We can do better! subroutine variant1(n) implicit none integer, intent(in) [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[30],"class_list":["post-1942","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-fortran"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1942"}],"version-history":[{"count":2,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1942\/revisions"}],"predecessor-version":[{"id":1944,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1942\/revisions\/1944"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1942"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}