Better way to mask a Fortran array?

别来无恙 提交于 2020-12-29 14:14:05

问题


I am wanting to mask a Fortran array. Here's the way I am currently doing it...

where (my_array <=15.0)
    mask_array = 1
elsewhere
    mask_array = 0
end where

So then I get my masked array with:

masked = my_array * mask_array

Is there a more concise way to do this?


回答1:


Use the MERGE intrinsic function:

masked = my_array * merge(1,0,my_array<=15.0)



回答2:


Or, sticking with where,

masked = 0
where (my_array <=15.0) masked = my_array

I expect that there are differences, in speed and memory consumption, between the use of where and the use of merge but off the top of my head I don't know what they are.




回答3:


There are two different approaches already given here: one retaining where and one using merge. In the first, High Performance Mark mentions that there may be differences in speed and memory use (think about temporary arrays). I'll point out another potential consideration (without making a value judgment).

subroutine work_with_masked_where(my_array)
  real, intent(in) :: my_array(:)
  real, allocatable :: masked(:)

  allocate(masked(SIZE(my_array)), source=0.)
  where (my_array <=15.0) masked = my_array
  ! ...
 end subroutine

subroutine work_with_masked_merge(my_array)
  real, intent(in) :: my_array(:)
  real, allocatable :: masked(:)

  masked = MERGE(my_array, 0., my_array<=15.)
  ! ...
end subroutine

That is, the merge solution can use automatic allocation. Of course, there are times when one doesn't want this (such as when working with lots of my_arrays of the same size: there are often overheads when checking array sizes in these cases): use masked(:) = MERGE(...) after handling the allocation (which may be relevant even for the question code).



来源:https://stackoverflow.com/questions/28637105/better-way-to-mask-a-fortran-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!