Compare commits

...

1 Commits

2 changed files with 51 additions and 8 deletions

View File

@ -218,22 +218,32 @@ function inside(xc,yc,n,x,y)
real(wp_), intent(in) :: x,y
logical :: inside
integer, dimension(n) :: jint
real(wp_), dimension(n) :: xint
! real(wp_), dimension(n) :: xint
real(wp_), dimension(n+1) :: xclosed,yclosed
integer :: i,nj
xclosed(1:n)=xc(1:n)
yclosed(1:n)=yc(1:n)
xclosed(n+1)=xc(1)
yclosed(n+1)=yc(1)
! Count the number of segments for which y lies between
! yclosed(j) and yclosed(j+1)
! and store the indexes j in jint
call locate_unord(yclosed,n+1,y,jint,n,nj)
inside=.false.
if (nj==0) return
! Determine the x coordinate, along the previously identified segments,
! required to match the y coordinate of the inquired point,
! and count the segments to the left of the inquired point.
! An even number means that the point is outside the closed contour.
do i=1,nj
xint(i)=intlinf(yclosed(jint(i)),xclosed(jint(i)), &
yclosed(jint(i)+1),xclosed(jint(i)+1),y)
if (x>intlinf(yclosed(jint(i)),xclosed(jint(i)), &
yclosed(jint(i)+1),xclosed(jint(i)+1),y)) &
inside=.not.inside
! xint(i)=intlinf(yclosed(jint(i)),xclosed(jint(i)), &
! yclosed(jint(i)+1),xclosed(jint(i)+1),y)
end do
call bubble(xint,nj)
inside=(mod(locatef(xint,nj,x),2)==1)
! call bubble(xint,nj)
! inside=(mod(locatef(xint,nj,x),2)==1)
end function inside

View File

@ -93,11 +93,44 @@ contains
real(wp_), intent(in) :: x
integer, dimension(m), intent(inout) :: j
integer :: i
logical :: larger_than_last
nj=0
do i=1,n-1
if (x>a(i).neqv.x>a(i+1)) then
! do i=1,n-1
! if (x>a(i).neqv.x>a(i+1)) then
! nj=nj+1
! if (nj<=m) j(nj)=i
! end if
! end do
!
! Alternative formulation
! Should reduce the number of evaluations of i+1 and x>a(i)
! * For an array a with only two changes of derivative
! (e.g., z of convex R,z contour) and x in range:
! * comparisons between floats (x>a(i)): 2*(n-1) --> n+2
! * comparisons between booleans (.neqv.): n-1 --> n-1
! * comparisons between integers (n<2): 0 --> 1
! * sum of integers (i+1, i-1): n --> 2
! * booleans assigments: 0 --> 3
! * For x out of range:
! * comparisons between floats (x>a(i)): 2*(n-1) --> n
! * comparisons between booleans (.neqv.): n-1 --> n-1
! * comparisons between integers (n<2): 0 --> 1
! * sum of integers (i+1, i-1): n --> 0
! * booleans assigments: 0 --> 1
! * For a elements alternated above/below x:
! * comparisons between floats (x>a(i)): 2*(n-1) --> 2*(n-1)+1
! * comparisons between booleans (.neqv.): n-1 --> n-1
! * comparisons between integers (n<2): 0 --> 1
! * sum of integers (i+1, i-1): n --> n-1
! * booleans assigments: 0 --> n
if (n<2) return
larger_than_last = (x>a(1))
do i=2,n
if (x>a(i).neqv.larger_than_last) then
larger_than_last = (x>a(i))
nj=nj+1
if (nj<=m) j(nj)=i
if (nj<=m) j(nj)=i-1
end if
end do
end subroutine locate_unord