From: Jim Xia on
On Feb 22, 11:09 am, nos...(a)see.signature (Richard Maine) wrote:
> Jim Xia <jim...(a)hotmail.com> wrote:
> > The optional keyword has to be specified on the interface declaration,
> > not the caller (the call side).
>
> Well, that seems a bit misleading. It has to be specified in the actual
> code for the procedure. That's the important part. There doesn't even
> need to be an "interface declaration", except to the extent that you
> mean the declarations in the procedure itself. Hmm. It does occur to me
> that you might well mean that. But mostly I deduce that just because I'd
> expect you to know it rather than because the words tell me that. I bet
> a lot of people would misread the words as referring to an interface
> body.

Yes, I meant both places: interface declaration and definition. A
procedure with OPTIONAL dummy has to have an explicit interface. The
impression I have is that Monir has F77 code, and he wants to reuse
the code to do this. In that case, an explicit interface block is
needed in the routines that actually make calls to mySort. And of
course the actual definition for mySort has to be modified as well.

Cheers,

Jim
From: monir on
On Feb 22, 11:16 am, Jim Xia <jim...(a)hotmail.com> wrote:
> On Feb 22, 11:09 am, nos...(a)see.signature (Richard Maine) wrote:
>
> > Jim Xia <jim...(a)hotmail.com> wrote:
> > > The optional keyword has to be specified on the interface declaration,
> > > not the caller (the call side).
>

Thank you all for your prompt and helpful replies.
{OPTIONAL attribute, PRESENT intrinsic, modify the declarations of all
the dummy arguments, interface declaration, optional keyword,
interface & arguments of rank 2 or higher; etc.}

As some of you have suggested, attached below please find an
abbreviated F77 code of the 4-variable sort version, which works fine.
(I had to simplify and shorten the variables' names for posting and
easy reading).

The question once again is whether one can use the same 4-variable
mySort() routine for 3-variable, 2-variable, and 1-variable sort, as
the case maybe, by simply modifying the calling statement in main;
using possibly "OPTIONAL" arguments in the argument list or in the
interface or some other procedure.

Your help would be greatly appreciated.

Regards.
Monir

===============================================
Program Test
....................
Parameter (maxi=10, maxj=10, maxk=30,maxm=15)
real vx(maxi,maxj,maxk,maxm), vy(maxi,maxj,maxk,maxm)
real vz(maxi,maxj,maxk,maxm), vt(maxi,maxj,maxk,maxm)
real x(maxi,maxj,maxk,maxm), y(maxi,maxj,maxk,maxm)
real z(maxi,maxj,maxk,maxm), t(maxi,maxj,maxk,maxm),
.................................
!--actual array dims
ni= whatever
nj= whatever
nk= whatever
nm= whatever
!.....................................my code 1...
!--sort the 4 arrays vx, vy, vz, vt in ascending order
! wrt x, y, z, t
Call mySort (x,vx,ni, y,vy,nj,
z,vz,nk, t,vt,nm)
...................................................
!.....................................my code 2...
End Program Test

===============================================
Subroutine mySort (x,vx,ni, y,vy,nj,
z,vz,nk, t,vt,nm)
..........................
c--sort input coordinates x, y, z, t in ascending order
c wrt the 4 coordinates and make the rearrangements of
c the corresponding functions components vx, vy, vz, vt

Parameter (maxi=10, maxj=10, maxk=30,maxm=15)
real x(maxi,maxj,maxk,maxm), y(maxi,maxj,maxk,maxm)
real z(maxi,maxj,maxk,maxm), t(maxi,maxj,maxk,maxm)
real vx(maxi,maxj,maxk,maxm), vy(maxi,maxj,maxk,maxm)
real vz(maxi,maxj,maxk,maxm), vt(maxi,maxj,maxk,maxm)

real tempx(30), tempy(30), tempz(30), tempt(30) !largest of
parameter constants
real tempvx(30), tempvy(30), tempvz(30), tempvt(30)
dimension wksp(30), iwksp(30)
!....................................my code 3...
c--sort w.r.t. X
do 20 j=1,nj
do 20 k=1,nk
do 20 m=1,nm
do 30 i=1, ni
tempx(i) = x(i,j,k,m)
tempy(i) = y(i,j,k,m)
tempz(i) = z(i,j,k,m)
tempt(i) = t(i,j,k,m)
tempvx(i) = vx(i,j,k,m)
tempvy(i) = vy(i,j,k,m)
tempvz(i) = vz(i,j,k,m)
tempvt(i) = vt(i,j,k,m)
30 continue

call sort4(ni, tempx, tempy, tempz, tempt
tempvx, tempvy, tempvz, tempvt, wksp,iwksp)
do 40 i=1, ni
x(i,j,k,m) = tempx(i)
y(i,j,k,m) = tempy(i)
z(i,j,k,m) = tempz(i)
t(i,j,k,m) = tempt(i)

vx(i,j,k,m) = tempvx(i)
vy(i,j,k,m) = tempvy(i)
vz(i,j,k,m) = tempvz(i)
vt(i,j,k,m) = tempvt(i)
40 continue
20 continue

!..................................my code 4...
Return
End subroutine mySort

===============================================
Subroutine Sort44 (N, RA, RB, RC, RD, RE, RF, RG,RH, WKSP,IWKSP)
........................
c--sorts an array RA of length N into ascending numerical order while
c making the corresponding rearrangements of the arrays RB, RC, RD,
c RE, RF, RG, RH
..........................
real RA(N), RB(N), RC(N), RD(N), RE(N), RF(N), RG(N), RH(N)
dimension WKSP(N), IWKSP(N)

!.......................................my code 5...
Return
End subroutine Sort44
From: glen herrmannsfeldt on
monir <monirg(a)mondenet.com> wrote:
(snip)

> Thank you all for your prompt and helpful replies.
> {OPTIONAL attribute, PRESENT intrinsic, modify the declarations of all
> the dummy arguments, interface declaration, optional keyword,
> interface & arguments of rank 2 or higher; etc.}
(snip)

> The question once again is whether one can use the same 4-variable
> mySort() routine for 3-variable, 2-variable, and 1-variable sort, as
> the case maybe, by simply modifying the calling statement in main;
> using possibly "OPTIONAL" arguments in the argument list or in the
> interface or some other procedure.

(see later posts on this one)

(snip)

> c--sort w.r.t. X
> do 20 j=1,nj
> do 20 k=1,nk
> do 20 m=1,nm
> do 30 i=1, ni
> tempx(i) = x(i,j,k,m)
> tempy(i) = y(i,j,k,m)
> tempz(i) = z(i,j,k,m)
> tempt(i) = t(i,j,k,m)
> tempvx(i) = vx(i,j,k,m)
> tempvy(i) = vy(i,j,k,m)
> tempvz(i) = vz(i,j,k,m)
> tempvt(i) = vt(i,j,k,m)
> 30 continue

As I understand this, in one loop you are sorting w.r.t. X,
and then (though you didn't post it), later w.r.t. Y, Z, and T.

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. You don't mention how big the arrays
are, or how fast the program needs to be.

In most cases, it is faster to do one big sort, than four
nested sorts. In the days of external sorting on tape, though,
it might not have been unusual to do nested sorting.

-- glen


From: glen herrmannsfeldt on
Reinhold Bader <Bader(a)lrz.de> wrote:
(snip)

>> 3) Now suppose instead of a 4-variable sort, I'm interested in only
>> three 3D variables or two 2D variables or even one 1D variable sort.
>> Is there a way in Fortran to use the same routine mySort() in this
>> case (F77/g95) ??

> If the subroutine has the interface

(also, the only interface that Fortran 77 allowed)

> subroutine mysort(absc, values, nmax)
> real :: absc(*)
> real :: values(*)
> integer :: nmax
> ..
> end subroutine

> you can also call this with arguments of rank 2 or higher:

> real :: absc(m, n), values(n, m)
> :
> call mysort(absc(1,1), values(1,1), m*n)
>
> Note that the first array elements are specified as arguments here.

>> Is my question related to Rank and/or Dynamic Array feature (F90 and
>> later) ??
>> If it is not possible in Fortran, is there a better way than writing 4
>> almost identical routines; one for each case ??

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?

Well, you could sort the four arrays separately. That is, separately
sort vx, vy, vz, and vt, based on copies of x, y, z, and t.

In any case, as noted above, Fortran allows for subroutines to
work on arbitrary rank arrays as if they are a different rank,
usually rank one. The array elements are seen in the same order that
they are stored in memory, that is, with the leftmost subscript
varying fastest.

-- glen



>> 4) If I recall correctly, some programming languages/compilers allow
>> the use of "Optional" argument in the calling statement if the
>> argument is not needed. However, once an argument is made Optional,
>> all the arguments that follow must be made Optional as well.
>
> Fortran allows to specify the OPTIONAL attribute on a dummy argument.
> It is not required that any dummy following the first one itself
> must have the OPTIONAL attribute. Note that it is recommended to use
> the PRESENT intrinsic to check whether an actual argument was
> specified:
>
>
> subroutine foo(x, ...)
> real, optional :: x
> :
> if (present(x)) then
> ... ! reference and/or define x
> end if
> :
> end subroutine
>
> However, for the scenario you describe here optional arguments are
> probably not a good choice.
>
>> (and that's why the argument list in Item 2 above was arranged that
>> way)
>> For example, for a 3-variable sort, the call statement may look
>> something like:
>> Call mySort (x,vx,maxi,
>> y,vy,maxj,
>> z,vz,maxk,
>> optional t,optional vt,optional maxm)
>>
>> 5) I've searched the net using keywords: fortran+optional, optional
>> +argument, etc. with no results directly relevant.
>>
>> Could someone please comment and provide some guidance on how to.
>>
>> Thank you kindly.
>> Monir
>
>
> Regards
> Reinhold
From: Colin Watters on

"monir" <monirg(a)mondenet.com> wrote in message
news:b32d1782-a734-4e4b-930a-fd0e35e68ae6(a)z39g2000vbb.googlegroups.com...
On Feb 22, 11:16 am, Jim Xia <jim...(a)hotmail.com> wrote:
> On Feb 22, 11:09 am, nos...(a)see.signature (Richard Maine) wrote:
>
> > Jim Xia <jim...(a)hotmail.com> wrote:
> > > The optional keyword has to be specified on the interface
> > > declaration,
> > > not the caller (the call side).
>

> Thank you all for your prompt and helpful replies.
> {OPTIONAL attribute, PRESENT intrinsic, modify the declarations of all
> the dummy arguments, interface declaration, optional keyword,
> interface & arguments of rank 2 or higher; etc.}

> As some of you have suggested, attached below please find an
> abbreviated F77 code of the 4-variable sort version, which works fine.
> (I had to simplify and shorten the variables' names for posting and
> easy reading).

> The question once again is whether one can use the same 4-variable
> mySort() routine for 3-variable, 2-variable, and 1-variable sort, as
> the case maybe, by simply modifying the calling statement in main;
> using possibly "OPTIONAL" arguments in the argument list or in the
> interface or some other procedure.

> Your help would be greatly appreciated.


Doubtless it will be possible to do what you ask, but it may well prove to
be very long-winded and unsatisfying. And it depends on eaxctly what is
going on in subroutine sort44.

One approach is to rewrite sort44 so it doesn't require all the extra
arguments that accept the "corresponding rearrangements". Instead, return
just an array of integers (IA) that allow the array RA to be addressed in
sorted order. Then the code in mysort can be modified to use the necessarry
"if(present(t))" clauses to ensure the optional arguments are manipulated
only when available. The "manipulation" would comprise use of the IA array
to re-arrange them.

Another is to do plant the "if(present"s in sort44, but this as I say may
be unreasonably difficult (or indeed may be easier), depending on the code
therein.

--
Qolin

Email: my qname at domain dot com
Domain: qomputing