cnvex Subroutine

private subroutine cnvex(n, a, h)

compute the upper convex hull of the set (i,a(i)), i.e., the set of vertices (i_k,a(i_k)), k=1,2,...,m, such that the points (i,a(i)) lie below the straight lines passing through two consecutive vertices. the abscissae of the vertices of the convex hull equal the indices of the true components of the logical output vector h. the used method requires o(nlog n) comparisons and is based on a divide-and-conquer technique. once the upper convex hull of two contiguous sets (say, {(1,a(1)),(2,a(2)),...,(k,a(k))} and {(k,a(k)), (k+1,a(k+1)),...,(q,a(q))}) have been computed, then the upper convex hull of their union is provided by the subroutine cmerge. the program starts with sets made up by two consecutive points, which trivially constitute a convex hull, then obtains sets of 3,5,9... points, up to arrive at the entire set. the program uses the subroutine cmerge; the subroutine cmerge uses the subroutines left, right and ctest. the latter tests the convexity of the angle formed by the points (i,a(i)), (j,a(j)), (k,a(k)) in the vertex (j,a(j)) up to within a given tolerance toler, where i<j<k.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n
real(kind=wp) :: a(n)
logical, intent(out) :: h(n)

Calls

proc~~cnvex~~CallsGraph proc~cnvex polyroots_module::cnvex proc~cmerge polyroots_module::cmerge proc~cnvex->proc~cmerge proc~ctest polyroots_module::ctest proc~cmerge->proc~ctest proc~left polyroots_module::left proc~cmerge->proc~left proc~right polyroots_module::right proc~cmerge->proc~right

Called by

proc~~cnvex~~CalledByGraph proc~cnvex polyroots_module::cnvex proc~start polyroots_module::start proc~start->proc~cnvex proc~polzeros polyroots_module::polzeros proc~polzeros->proc~start

Source Code

    subroutine cnvex(n, a, h)

        !! compute the upper convex hull of the set (i,a(i)), i.e., the set of
        !! vertices (i_k,a(i_k)), k=1,2,...,m, such that the points (i,a(i)) lie
        !! below the straight lines passing through two consecutive vertices.
        !! the abscissae of the vertices of the convex hull equal the indices of
        !! the true  components of the logical output vector h.
        !! the used method requires o(nlog n) comparisons and is based on a
        !! divide-and-conquer technique. once the upper convex hull of two
        !! contiguous sets  (say, {(1,a(1)),(2,a(2)),...,(k,a(k))} and
        !! {(k,a(k)), (k+1,a(k+1)),...,(q,a(q))}) have been computed, then
        !! the upper convex hull of their union is provided by the subroutine
        !! cmerge. the program starts with sets made up by two consecutive
        !! points, which trivially constitute a convex hull, then obtains sets
        !! of 3,5,9... points,  up to  arrive at the entire set.
        !! the program uses the subroutine  cmerge; the subroutine cmerge uses
        !! the subroutines left, right and ctest. the latter tests the convexity
        !! of the angle formed by the points (i,a(i)), (j,a(j)), (k,a(k)) in the
        !! vertex (j,a(j)) up to within a given tolerance toler, where i<j<k.

        implicit none

        integer,intent(in) :: n
        real(wp) :: a(n)
        logical,intent(out) :: h(n)

        integer :: i, j, k, m, nj, jc

        do i = 1, n
            h(i) = .true.
        end do
        ! compute k such that n-2<=2**k<n-1
        k = int(log(n - 2.0_wp)/log(2.0_wp))
        if (2**(k + 1) <= (n - 2)) k = k + 1
        ! for each m=1,2,4,8,...,2**k, consider the nj pairs of consecutive
        ! sets made up by m+1 points having the common vertex
        ! (jc,a(jc)), where jc=m*(2*j+1)+1 and j=0,...,nj,
        ! nj=max(0,int((n-2-m)/(m+m))).
        ! compute the upper convex hull of their union by means of the
        ! subroutine cmerge
        m = 1
        do i = 0, k
            nj = max(0, int((n - 2 - m)/(m + m)))
            do j = 0, nj
                jc = (j + j + 1)*m + 1
                call cmerge(n, a, jc, m, h)
            end do
            m = m + m
        end do

    end subroutine cnvex