From: glen herrmannsfeldt on
monir <monirg(a)mondenet.com> wrote:

> 1) Let us say I've a routine mySort() which sorts four 4D array
> variables in increasing order wrt there abscissa:
> ..abscissa x(i,j,k,m)
> ..abscissa y(i,j,k,m)
> ..abscissa z(i,j,k,m)
> ..abscissa t(i,j,k,m)
> ....variable vx(i,j,k,m)
> ....variable vy(i,j,k,m)
> ....variable vz(i,j,k,m)
> ....variable vt(i,j,k,m)

The standard C library includes a sort routine called qsort (which
may, but isn't required to implement, the quicksort algorithm).

I wonder if it is possible to call qsort() from Fortran.
One complication is that qsort() requires a C function pointer...

-- glen
From: glen herrmannsfeldt on
(snip, I wrote)

> I wonder if it is possible to call qsort() from Fortran.
> One complication is that qsort() requires a C function pointer...

So far this seems to work with gfortran. I haven't found the
right interface, using all the right combinations of bind(c),
value, and type(c_funptr) to make gfortran happy.

For the OP to use qsort(), the data would have to be rearranged
such that the variables that are supposed to stay together are
contiguous in memory.

! attempt to sort using C qsort
use, intrinsic:: iso_C_binding
integer x(10)
data x/1,4,3,8,2,6,9,7,0,5/
external icmp
bind(c) qsort
call qsort(x,%val(10),%val(4),icmp)
print *,x
end
!
integer function icmp(a,b)
if(a.gt.b) then
icmp=1
else if(a.lt.b) then
icmp=-1
else
icmp=0
endif
return
end

From: monir on
On Feb 22, 7:18 pm, glen herrmannsfeldt <g...(a)ugcs.caltech.edu> wrote:
> monir <mon...(a)mondenet.com> wrote:
> > 1) Let us say I've a routine mySort() which sorts four 4D array
> > variables in increasing order wrt there abscissa:
>

glen herrmannsfeldt wrote:

>Note that many fast sort routines are not stable. That is,
>sorting in Y may not keep the elements as previously sorted
>in the same order.

My sorting routine mySort() works fine and as desired for a 4-variable
4D sort.

>You don't mention how big the arrays
>are, or how fast the program needs to be.

The max dims are given by the Parameter statement in the posted
abbreviated code:
....Parameter (maxi=10, maxj=10, maxk=30,maxm=15)
Appreciating the relatively small size of the arrays, sorting speed is
not a factor.

>This is a little confusing to follow. You have four arrays that
>are four dimensional (rank four). Are the other cases three arrays
>of rank three, and two arrays of rank two?

Yes, as mentioned in my OP item 3.

>The standard C library includes a sort routine called qsort (which
>may, but isn't required to implement, the quicksort algorithm).

>I wonder if it is possible to call qsort() from Fortran.
>One complication is that qsort() requires a C function pointer...

As indicated above, there's no problem with my four 4D variables
sorting routine mySort().
The question is whether one can still use the same mySort() routine as
is but for three 3D variables sort, two 2D variables sort and even one
1D variable sort, by say "blocking" inapplicable arguments in the
list, or perhaps using some sort of "Optional" arguments, or ......
The alternative is to write several almost identical routines; one for
each case, which I'm trying to avoid if by all means possible!.
Some responders have already indicated that it can be done in F77/g95
using:
>interface declaration and definition ... a procedure with OPTIONAL dummy
>with an explicit interface ...

Jim Xia wrote:
>If you'd like to learn how to do this in coding, please post
>the original interface for mySort

I've just posted an abbreviated version of the code.

Regards.
Monir
From: glen herrmannsfeldt on
glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:
> (snip, I wrote)

>> I wonder if it is possible to call qsort() from Fortran.
>> One complication is that qsort() requires a C function pointer...

Trying to get the right interface, using all the right
combinations of bind(c), value, and type(c_funptr), I so far
have the following. It doesn't seem to make gfortran happy.
One problem was the declaration for compar inside the interface
for qsort. With this last change, it gets an internal compiler
error from gfortran, but I am not so sure that it is the right
way to declare all of this.

The specific problem is the proper declaration for a function
pointer argument to a binc(c) function, and the proper way
to call the function with a C function pointer to a bind(c)
Fortran function.

! attempt to sort using C qsort
use, intrinsic:: iso_C_binding
integer x(10)
data x/1,4,3,8,2,6,9,7,0,5/
interface
subroutine qsort(array,n,m,compar) bind(c)
use, intrinsic:: iso_C_binding
type(c_funptr) :: compar
integer array(*)
integer(c_int) ,value:: n,m
end subroutine
integer function icmp(a,b) bind(c)
use, intrinsic:: iso_C_binding
integer :: a,b
end function
end interface
call qsort(x,10,4,c_funloc(icmp))
print *,x
end
!
integer function icmp(a,b)
if(a.gt.b) then
icmp=1
else if(a.lt.b) then
icmp=-1
else
icmp=0
endif
return
end
From: robin on
"glen herrmannsfeldt" <gah(a)ugcs.caltech.edu> wrote in message news:hlv6t2$7d7$3(a)naig.caltech.edu...
| monir <monirg(a)mondenet.com> wrote:
|
| > 1) Let us say I've a routine mySort() which sorts four 4D array
| > variables in increasing order wrt there abscissa:
| > ..abscissa x(i,j,k,m)
| > ..abscissa y(i,j,k,m)
| > ..abscissa z(i,j,k,m)
| > ..abscissa t(i,j,k,m)
| > ....variable vx(i,j,k,m)
| > ....variable vy(i,j,k,m)
| > ....variable vz(i,j,k,m)
| > ....variable vt(i,j,k,m)
|
| The standard C library includes a sort routine called qsort (which
| may, but isn't required to implement, the quicksort algorithm).
|
| I wonder if it is possible to call qsort() from Fortran.

Why bother?
Quicksort is a relatively short procedure to code,
and codes in Fortran are readily available.

| One complication is that qsort() requires a C function pointer...

Again, why bother?