Remove repeated elements in a 2D array in Fortran

怎甘沉沦 提交于 2019-12-25 08:47:16

问题


I would like to know whether it is possible to have a function that erases all of the 2D repeated nodes from an array, i.e.:

A(xy,1:2)

A(xy,1) = /1,2,4,5,5,9,6,8,2,5,4/

A(xy,2) = /5,2,5,6,7,6,6,3,7,6,6/

After

A(xy,1) = /1,2,4,5,5,9,6,8,2,4/

A(xy,2) = /5,2,5,6,7,6,6,3,7,6/


When I try to execute @HighPerformanceMark's code in a blank program, there are several compiling errors that I do not get:

  repeating.f90:24.20:

       mask(ix) = NOT(ANY(arraya(1,:ix-1)==arraya(1,ix).AND.&
                      1
  Error: 'i' argument of 'not' intrinsic at (1) must be INTEGER
  repeating.f90:29.11:

    ALLOCATE(index_vector, source=PACK([(ix, ix=1,numcols) ],mask))
             1
  Error: Array specification required in ALLOCATE statement at (1)
  repeating.f90:32.11:
...

What can you say about this?


回答1:


Yes, here's one way of doing what you want. Note that this will copy the unique elements of array A into a new array called B rather than resize A on the fly. I've called the arrays arraya and arrayb because 1-character names go against my coding standards.

PROGRAM test

  USE iso_fortran_env

  IMPLICIT NONE

  INTEGER, PARAMETER :: numrows = 2
  INTEGER, PARAMETER :: numcols = 11

  INTEGER, DIMENSION(numrows,numcols) :: arraya
  LOGICAL, DIMENSION(:), ALLOCATABLE :: mask
  INTEGER, DIMENSION(:,:), ALLOCATABLE :: arrayb
  INTEGER :: ix
  INTEGER, DIMENSION(:), ALLOCATABLE :: index_vector

  arraya(1,:) = [1,2,4,5,5,9,6,8,2,5,4]
  arraya(2,:) = [5,2,5,6,7,6,6,3,7,6,6]

  ! First, find the duplicate elements
  ALLOCATE(mask(numcols))
  mask = .TRUE.

  DO ix = numcols,2,-1
     mask(ix) = .NOT.(ANY(arraya(1,:ix-1)==arraya(1,ix).AND.&
                    arraya(2,:ix-1)==arraya(2,ix)))
  END DO

  ! Make an index vector
  ALLOCATE(index_vector, source=PACK([(ix, ix=1,numcols) ],mask))

  ! Now copy the unique elements of a into b
  ALLOCATE(arrayb, source=arraya(:,index_vector))

END PROGRAM test

Note also:

  • I've written this as a program, you might want to rewrite it into a function which returns what I've called arrayb.
  • There's no error checking or any of that sort of stuff, this is not production-ready code.
  • You could probably dispense with index_vector and rewrite the last statement like this ALLOCATE(arrayb, source=arraya(:,PACK([(ix, ix=1,numcols) ],mask))) but (a) that's a wee bit cryptic and (b) I haven't tested it.
  • I've only tested this on your input data and a few minor variations.
  • This keeps the first (leftmost) instance of duplicated elements.


来源:https://stackoverflow.com/questions/14137610/remove-repeated-elements-in-a-2d-array-in-fortran

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