Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the performance in nearest_index #1445

Merged
merged 3 commits into from
Jan 22, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 42 additions & 44 deletions axis_utils/include/axis_utils2.inc
Original file line number Diff line number Diff line change
Expand Up @@ -306,64 +306,62 @@
integer :: ia !< dimension of "array"
integer :: i !< For looping through "array"

logical :: increasing !< .True. if the array is increasing

ia = SIZE(array(:))

! check if array is monotonous
! check if array is increasing
increasing = .true.
DO i = 2, ia-1
IF( (array(i-1)<array(i).AND.array(i)>array(i+1)) .OR. (array(i-1)>array(i).AND.array(i)<array(i+1))) THEN
! <ERROR STATUS="FATAL">array NOT monotonously ordered</ERROR>
CALL mpp_error(FATAL, 'axis_utils2::nearest_index array is NOT monotonously ordered')
END IF
IF( array(i) .lt. array(i-1)) then
increasing = .false.
exit
endif
END DO

if (array(1) < array(ia)) then
!< increasing array
if (.not. increasing) then
! if not increasing, check that it is decreasing
DO i = 2, ia-1
IF( array(i) .gt. array(i-1)) &
call mpp_error(FATAL, 'axis_utils2::nearest_index array is NOT monotonously ordered')
END DO
endif

array_is_increasing: if (increasing) then
!< Check if the rval is outside the range of the array
if (rval < array(1)) then
NEAREST_INDEX_ = 1
return
elseif (rval > array(ia)) then
NEAREST_INDEX_ = ia
return
if (rval .le. array(1)) then
bensonr marked this conversation as resolved.
Show resolved Hide resolved
NEAREST_INDEX_ = 1
return
elseif (rval .ge. array(ia)) then
NEAREST_INDEX_ = ia
return
endif

DO i = 1, ia-1
IF ( (array(i)<=rval).AND.(array(i+1)>= rval) ) THEN
IF( rval - array(i) <= array(i+1) - rval ) THEN
NEAREST_INDEX_ = i
return
ELSE
NEAREST_INDEX_ = i+1
return
ENDIF
EXIT
END IF
DO i = 2, ia
if (rval .le. array(i)) then
NEAREST_INDEX_ = i
if (array(i) -rval .gt. rval - array(i-1)) NEAREST_INDEX_ = i - 1
return
endif
END DO
else
!< Decreasing Array

else !array_is_decreasing
!< Check if the rval is outside the range of the array
if (rval < array(ia)) then
NEAREST_INDEX_ = ia
return
elseif (rval > array(1)) then
NEAREST_INDEX_ = 1
return
if (rval .le. array(ia)) then
NEAREST_INDEX_ = ia
return
elseif (rval .gt. array(1)) then
NEAREST_INDEX_ = 1
return
endif

DO i = 1, ia-1
IF ( (array(i)>=rval).AND.(array(i+1)<= rval) ) THEN
IF ( array(i)-rval <= rval-array(i+1) ) THEN
NEAREST_INDEX_ = i
return
ELSE
NEAREST_INDEX_ = i+1
return
END IF
END IF
DO i = 2, ia
if (rval .ge. array(i)) then
NEAREST_INDEX_ = i
if (rval - array(i) .gt. array(i-1) -rval ) NEAREST_INDEX_ = i - 1
return
endif
END DO
endif
endif array_is_increasing
end function NEAREST_INDEX_

!#############################################################################
Expand Down
Loading