Re: busting sp datatypes
  Home FAQ Contact Sign in
comp.lang.fortran only
 
Advanced search
POPULAR GROUPS

more...

 Up
Re: busting sp datatypes         

Group: comp.lang.fortran · Group Profile
Author: Ron Ford
Date: Aug 27, 2008 19:21

On Wed, 27 Aug 2008 00:40:58 -0700, Richard Maine posted:
> Ron Ford wrote:

[re-ordered, for thematic reasons]
>> I still don't know what you mean with the word 'interp'.
>
> It is an abbreviation for "interpretation". It is the vernacular used
> for formal requests for interpretation of the standard. Insomuch as the
> official precedures for such things are cumbersome and slow,
> interpretation requests generally ought to be about things where the
> standard is flawed in some way, either being ambiguous, internally
> inconsistent, impractical to implement, or otherwise in need of repair.

I thought "interp" had to do with "interop." Never mind.
>
>> Had you read the thread more carefully, you may have seen the motivation to
>> posit that '4' was special,
>
> Possibly, but when it is hard for me to read the single sentences,
> reading the whole thread carefully is too much. I tend to not bother to
> try very hard. In any case, I wasn't asking about the motivation of the
> question, but rather about what the question actually was, which this
> didn't clarify. But anyway...

My thinking has been fairly muddled on this thread.:-(
>
>> qsort is in C's stdlib; can fortran make the necessary interface?
>
> I haven't looked at the interface to qsort. Being in stdlib is
> irrelevant to the question. Knowing what the interface actually is would
> be a lot more relevant.
>
> Yes, I could no doubt go look it up, if I were inclined to. Is there
> some reason why you ask me in particular and is it supposed to be
> related to anything in this thread? I'm not sure why I would be the
> particular designee and I don't see qsort or anything else about sorting
> upthread. I've been intentionally ignoring most of the separate thread
> about sorting, as it didn't seem to me to have much to do with Fortran,
> at least in the initial post that I read. I suppose it might later have
> drifted onto topic when I wasn't watching.

Again, I thought that you were spearheading interop, so I thought a C
question would be right up your alley.

This thread is to get this program that I've been kicking around able to
deal with larger numbers. While the routines I call are sorts, my
difficulties are getting the types to match on these calls.

What I have compiles but results in a run-time that makes no sense to me:
! timing sorts

module sort3
implicit none
integer, parameter :: i13 = selected_int_kind(13)
private
public :: selection_sort
! type definition includes only an integer
type, public :: address
integer(i13) :: zip_code
end type address
contains
recursive subroutine selection_sort (array_arg)
integer, parameter :: i13 = selected_int_kind(13)
type (address), dimension(:), intent (inout) &
:: array_arg
integer(i13) :: current_size
integer(i13) :: big
current_size = size (array_arg)
if (current_size > 0) then
big = maxloc(array_arg(:)%%zip_code, dim=1)
call swap (big, current_size)
call selection_sort (array_arg(1: current_size -1))
end if
contains
subroutine swap(i,j)
integer, parameter :: i13 = selected_int_kind(13)
integer(i13), intent (in) :: i,j
type (address) :: temp
temp = array_arg(i)
array_arg(i) = array_arg(j)
array_arg(j) = temp
end subroutine swap
end subroutine selection_sort
end module sort3

! Recursive Fortran 95 quicksort routine
! sorts integer numbers into ascending numerical order
! Author: Juli Rew, SCD Consulting (juliana@ucar.edu), 9/03
! Based on algorithm from Cormen et al., Introduction to Algorithms,
! 1997 printing

! Made F conformant by Walt Brainerd

module qsort_c_module

implicit none
public :: QsortC
private :: Partition

contains

recursive subroutine QsortC(A)
integer, parameter :: i13 = selected_int_kind(13)
integer(i13), intent(in out), dimension(:) :: A
integer (i13):: iq

if(size(A) > 1) then
call Partition(A, iq)
call QsortC(A(:iq-1))
call QsortC(A(iq:))
endif
end subroutine QsortC

subroutine Partition(A, marker)
integer, parameter :: i13 = selected_int_kind(13)
integer(i13), intent(in out), dimension(:) :: A
integer(i13), intent(out) :: marker
integer(i13) :: i, j
integer(i13) :: temp
integer(i13) :: x ! pivot point
x = A(1)
i= 0
j= size(A) + 1

do
j = j-1
do
if (A(j) <= x) exit
j = j-1
end do
i = i+1
do
if (A(i) >= x) exit
i = i+1
end do
if (i < j) then
! exchange A(i) and A(j)
temp = A(i)
A(i) = A(j)
A(j) = temp
elseif (i == j) then
marker = i+1
return
else
marker = i
return
endif
end do

end subroutine Partition

end module qsort_c_module

use qsort_c_module
use sort3
implicit none

integer, parameter :: i13 = selected_int_kind(13)

integer, parameter:: sides = 8
integer(i13), parameter:: trials = 3000000
integer(i13), parameter :: array_size = trials

integer, parameter:: bins = 50
integer, parameter:: percentile = 95

integer, dimension(sides)::A
integer(i13), dimension(trials)::C
integer, dimension(bins)::D
!! from qsort
integer(i13), dimension(trials)::F

type (address), dimension (array_size) :: data_array

integer:: b, ii, i, counter, &
tab, maxput, c1, c2, diff2, c3, c4
real:: harvest, tot, t1, t2, diff, t3, t4

! seed random num generator

CALL init_random_seed

! prime the pump
call random_number(harvest)
b = 3 + nint(10*harvest)
do i=1,b
call random_number(harvest)
print *, i, harvest
end do

! main control

! outer loop is the number of trials
C = 0
do ii=1,trials
tab = 0
A = 0
! inner loop rolls die till all values attained
do
call random_number(harvest)
b = ceiling(harvest*real(sides))
A(b) = A(b) + 1 !this is line 158
! count until all outcomes non-zero
counter = 0
do i = 1, sides
if (real(A(i)) > .5) then
counter = counter + 1
end if
end do
tab = tab + 1
if (counter == sides) then
C(ii) = tab
exit
end if
end do !inner
end do !outer

! end main control
! print *, "C is", C

! sort into bins
D=0
maxput = bins
do ii =1, trials
if (C(ii) > maxput) then
C(ii) = maxput
end if
D(C(ii))=D(C(ii)) + 1
end do
tot= sum(D)
print *, "total trials=",tot

! determine 95th percentile
tot = 0.01 *trials*real(percentile)
print *, "95th %% is", tot

counter = 0
do ii = 1, bins
counter = counter + D(ii)

if (real(counter).ge. tot) then
exit
end if
end do
print *, "95th percentile was in bin number", ii

! equate C with data_array

do i=1,array_size
data_array(i)%%zip_code=C(i)
end do

! time the sorts
call system_clock (c1)
call cpu_time (t1)
!call selection_sort (data_array(1:array_size))
call system_clock (c2)
call cpu_time (t2)
diff=t2-t1
diff2=c2-c1
print *, "system clock for selection sort was ", diff
print *, "cpu time for selection sort was ", diff2

F=C
call system_clock (c3)
call cpu_time (t3)
call QsortC(F)
call cpu_time (t4)
call system_clock (c4)
diff=t4-t3
diff2=c4-c3
print *, "system clock for qsort was ", diff
print *, "cpu time for qsort was ", diff2

! output

!print *, "quicksorted", F
!print *, "selection sorted", data_array

b = nint(tot)
print *, "b=", b
print *, data_array(b)

! end output
contains
SUBROUTINE init_random_seed()
INTEGER :: i, n, clock
INTEGER, DIMENSION(:), ALLOCATABLE :: seed

CALL RANDOM_SEED(size = n)
print *, "n=", n
ALLOCATE(seed(n))

CALL SYSTEM_CLOCK(COUNT=clock)
print *, "clock=", clock

seed = clock + 37 * (/ (i - 1, i = 1, n) /)
CALL RANDOM_SEED(PUT = seed)
print *, "seed= ", seed

DEALLOCATE(seed)
END SUBROUTINE
end program
! gfortran -o sort -fbounds-check freeformat50.f95

F:\gfortran\source>gfortran -o sort -fbounds-check freeformat50.f95

! I get nothing from gfortran with these switches ^^^^^^.

F:\gfortran\source>sort
n= 8
clock= 108897905
seed= 108897905 108897942 108897979 108898016 108898053
108898090
108898127 108898164
1 0.42305011
2 8.57861638E-02
3 0.40694624
At line 158 of file freeformat50.f95
Fortran runtime error: Array reference out of bounds for array 'a', lower
bound
of dimension 1 exceeded (0 < 1)

F:\gfortran\source>

I marked line 158 in the main control, where A represents the outcomes of
rolling an eight-sided die.

My strategy this time around has been to add the i13 kind as sparingly as
possible. Typically, the compiler complains that kinds are unlike and
dummy and actual args are not the same. So it is that I've had to add
integer, parameter :: i13 = selected_int_kind(13)
in four different places.

The call to selection sort is currently commented out as for larger
numbers, it is prohibitively slow. Grateful for any tips.
--
We must respect the other fellow's religion, but only in the sense and to
the extent that we respect his theory that his wife is beautiful and his
children smart. 5
H. L. Mencken
no comments
diggit! del.icio.us! reddit!