How to make a function work with different type and kind typeargument

This is a discussion on How to make a function work with different type and kind typeargument within the Fortran forums in Programming Languages category; Hi, the intrinsic sin(x), cos(x), etc, work with arguments of general type and kind type. Suppose I want to write a function mysin(x) which just calls sin(x) and, like sin(x), must work with general type and kind type argument. I can achieve the generality of type through overloading, however how can I obtain generality of kind type? Best regards, deltaquattro...

Go Back   Application Development Forum > Programming Languages > Fortran

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 09-04-2008, 10:58 AM
deltaquattro
Guest
 
Default How to make a function work with different type and kind typeargument

Hi,

the intrinsic sin(x), cos(x), etc, work with arguments of general type
and kind type. Suppose I want to write a function mysin(x) which just
calls sin(x) and, like sin(x), must work with general type and kind
type argument. I can achieve the generality of type through
overloading, however how can I obtain generality of kind type?

Best regards,

deltaquattro

Reply With Quote
  #2  
Old 09-04-2008, 11:09 AM
Paul van Delst
Guest
 
Default Re: How to make a function work with different type and kind typeargument

deltaquattro wrote:
> Hi,
>
> the intrinsic sin(x), cos(x), etc, work with arguments of general type
> and kind type. Suppose I want to write a function mysin(x) which just
> calls sin(x) and, like sin(x), must work with general type and kind
> type argument. I can achieve the generality of type through
> overloading, however how can I obtain generality of kind type?


Um, overloading? ) (Remember: TKR is used to distinguish)

E.g. in my compare_float_numbers module I have:

USE Type_Kinds, ONLY: Single, Double

INTERFACE Compare_Float
MODULE PROCEDURE Compare_Real_Single
MODULE PROCEDURE Compare_Real_Double
MODULE PROCEDURE Compare_Complex_Single
MODULE PROCEDURE Compare_Complex_Double
END INTERFACE Compare_Float

with

ELEMENTAL FUNCTION Compare_Real_Single( x, y, ULP, Percent ) RESULT( Compare )
REAL(Single), INTENT(IN) :: x
REAL(Single), INTENT(IN) :: y

ELEMENTAL FUNCTION Compare_Real_Double( x, y, ULP, Percent ) RESULT( Compare )
REAL(Double), INTENT(IN) :: x
REAL(Double), INTENT(IN) :: y

ELEMENTAL FUNCTION Compare_Complex_Single( x, y, ULP, Percent ) RESULT( Compare )
COMPLEX(Single), INTENT(IN) :: x
COMPLEX(Single), INTENT(IN) :: y

and

ELEMENTAL FUNCTION Compare_Complex_Double( x, y, ULP, Percent ) RESULT( Compare )
COMPLEX(Double), INTENT(IN) :: x
COMPLEX(Double), INTENT(IN) :: y


cheers,

paulv
Reply With Quote
  #3  
Old 09-04-2008, 11:28 AM
deltaquattro
Guest
 
Default Re: How to make a function work with different type and kind typeargument

On 4 Set, 17:09, Paul van Delst <Paul.vanDe...@noaa.gov> wrote:
> deltaquattro wrote:
> > Hi,

>
> > the intrinsic sin(x), cos(x), etc, work with arguments of general type
> > and kind type. Suppose I want to write a function mysin(x) which just
> > calls sin(x) and, like sin(x), must work with general type and kind
> > type argument. I can achieve the generality of type through
> > overloading, however how can I obtain generality of kind type?

>
> Um, overloading? ) (Remember: TKR is used to distinguish)
>
> E.g. in my compare_float_numbers module I have:
>
> * *USE Type_Kinds, ONLY: Single, Double
>
> * *INTERFACE Compare_Float
> * * *MODULE PROCEDURE Compare_Real_Single
> * * *MODULE PROCEDURE Compare_Real_Double
> * * *MODULE PROCEDURE Compare_Complex_Single
> * * *MODULE PROCEDURE Compare_Complex_Double
> * *END INTERFACE Compare_Float
>
> with
>
> * *ELEMENTAL FUNCTION Compare_Real_Single( x, y, ULP, Percent ) RESULT( Compare )
> * * *REAL(Single), INTENT(IN) :: x
> * * *REAL(Single), INTENT(IN) :: y
>
> * *ELEMENTAL FUNCTION Compare_Real_Double( x, y, ULP, Percent ) RESULT( Compare )
> * * *REAL(Double), INTENT(IN) :: x
> * * *REAL(Double), INTENT(IN) :: y
>
> * *ELEMENTAL FUNCTION Compare_Complex_Single( x, y, ULP, Percent ) RESULT( Compare )
> * * *COMPLEX(Single), INTENT(IN) :: x
> * * *COMPLEX(Single), INTENT(IN) :: y
>
> and
>
> * *ELEMENTAL FUNCTION Compare_Complex_Double( x, y, ULP, Percent ) RESULT( Compare )
> * * *COMPLEX(Double), INTENT(IN) :: x
> * * *COMPLEX(Double), INTENT(IN) :: y
>
> cheers,
>
> paulv


Hi, Paul,

long time no hear sure, I thought of that, but that's not nearly as
generic as the original sin function. While sin(x) works with any of
them on any machine, "your" mysin(x) only works with the two KTPs
Single and Double. Clearly, overloading cannot obtain the same level
of generality, since even the number of available KTPs varies from
machine to machine. So, I was wondering how "complete" generality is
achieved in the intrisic functions, and if this can be replicated by
user-defined functions.

Best regards


Reply With Quote
  #4  
Old 09-04-2008, 12:02 PM
Paul van Delst
Guest
 
Default Re: How to make a function work with different type and kind typeargument

deltaquattro wrote:
> On 4 Set, 17:09, Paul van Delst <Paul.vanDe...@noaa.gov> wrote:
>> deltaquattro wrote:
>>> Hi,
>>> the intrinsic sin(x), cos(x), etc, work with arguments of general type
>>> and kind type. Suppose I want to write a function mysin(x) which just
>>> calls sin(x) and, like sin(x), must work with general type and kind
>>> type argument. I can achieve the generality of type through
>>> overloading, however how can I obtain generality of kind type?

>> Um, overloading? ) (Remember: TKR is used to distinguish)
>>
>> E.g. in my compare_float_numbers module I have:
>>
>> USE Type_Kinds, ONLY: Single, Double
>>
>> INTERFACE Compare_Float
>> MODULE PROCEDURE Compare_Real_Single
>> MODULE PROCEDURE Compare_Real_Double
>> MODULE PROCEDURE Compare_Complex_Single
>> MODULE PROCEDURE Compare_Complex_Double
>> END INTERFACE Compare_Float
>>
>> with
>>
>> ELEMENTAL FUNCTION Compare_Real_Single( x, y, ULP, Percent ) RESULT( Compare )
>> REAL(Single), INTENT(IN) :: x
>> REAL(Single), INTENT(IN) :: y
>>
>> ELEMENTAL FUNCTION Compare_Real_Double( x, y, ULP, Percent ) RESULT( Compare )
>> REAL(Double), INTENT(IN) :: x
>> REAL(Double), INTENT(IN) :: y
>>
>> ELEMENTAL FUNCTION Compare_Complex_Single( x, y, ULP, Percent ) RESULT( Compare )
>> COMPLEX(Single), INTENT(IN) :: x
>> COMPLEX(Single), INTENT(IN) :: y
>>
>> and
>>
>> ELEMENTAL FUNCTION Compare_Complex_Double( x, y, ULP, Percent ) RESULT( Compare )
>> COMPLEX(Double), INTENT(IN) :: x
>> COMPLEX(Double), INTENT(IN) :: y
>>
>> cheers,
>>
>> paulv

>
> Hi, Paul,
>
> long time no hear sure, I thought of that, but that's not nearly as
> generic as the original sin function.


My perception anchor for how those things are implemented is the equivalent of what I
wrote above. The compiler writers faced the same problem, no?

> While sin(x) works with any of
> them on any machine, "your" mysin(x) only works with the two KTPs
> Single and Double. Clearly, overloading cannot obtain the same level
> of generality, since even the number of available KTPs varies from
> machine to machine.


Well, I don't think it's a completely fair comparison though - the sin(x) will work with
any kind type for the compiler in question. I.e. the number of valid kind types is fixed.
It seems you want "your" mysin(x) to work with any kind type allowed for any compiler.
That's a tougher problem.

I also have versions for "Quad" precision also, but some compilers I use don't support it.
Similarly for what I call "LLong" integers (in *-speak, integer*8).

> So, I was wondering how "complete" generality is
> achieved in the intrisic functions, and if this can be replicated by
> user-defined functions.


For a given compiler, yes. You just overload for all the allowed kind types.

cheers,

paulv
Reply With Quote
  #5  
Old 09-04-2008, 12:03 PM
Craig Powers
Guest
 
Default Re: How to make a function work with different type and kind typeargument

deltaquattro wrote:
>
> long time no hear sure, I thought of that, but that's not nearly as
> generic as the original sin function. While sin(x) works with any of
> them on any machine, "your" mysin(x) only works with the two KTPs
> Single and Double. Clearly, overloading cannot obtain the same level
> of generality, since even the number of available KTPs varies from
> machine to machine. So, I was wondering how "complete" generality is
> achieved in the intrisic functions, and if this can be replicated by
> user-defined functions.


The processors are not actually that general. They know what the total
list of available KINDs are, and they provide overloads for all of them.
Since there is no possibility of the addition of additional KINDs,
they don't need to provide any more generality than that.

What Paul suggested is a manual way of achieving the same result.
Reply With Quote
  #6  
Old 09-04-2008, 12:39 PM
Ron Shepard
Guest
 
Default Re: How to make a function work with different type and kind type argument

In article <g9p0s8$iif$1@registered.motzarella.org>,
Craig Powers <craig.powers@invalid.invalid> wrote:

> deltaquattro wrote:
> >
> > long time no hear sure, I thought of that, but that's not nearly as
> > generic as the original sin function. While sin(x) works with any of
> > them on any machine, "your" mysin(x) only works with the two KTPs
> > Single and Double. Clearly, overloading cannot obtain the same level
> > of generality, since even the number of available KTPs varies from
> > machine to machine. So, I was wondering how "complete" generality is
> > achieved in the intrisic functions, and if this can be replicated by
> > user-defined functions.

>
> The processors are not actually that general. They know what the total
> list of available KINDs are, and they provide overloads for all of them.
> Since there is no possibility of the addition of additional KINDs,
> they don't need to provide any more generality than that.
>
> What Paul suggested is a manual way of achieving the same result.


There may be ways to address these kinds of problems with the new
levels of abstraction provided by f2008. However, the "traditional"
way to solve these kinds of portability problems is with
preprocessors. This works best (or at least it is easiest) when the
only change required to the code is in the declarations, not in the
data structures or algorithms. Basically you write a program that
in turn writes the fortran code. The preprocessor loops over all of
the allowed types (that you provide as input), it outputs all of the
different KIND versions of the specific routines, along with the
interfaces required to have generic functionality. One particularly
good preprocessor for this kind of stuff is filepp:

http://www.cabaret.demon.co.uk/filepp/

$.02 -Ron Shepard
Reply With Quote
  #7  
Old 09-04-2008, 12:50 PM
Herman D. Knoble
Guest
 
Default Re: How to make a function work with different type and kind type argument

On Thu, 4 Sep 2008 07:58:34 -0700 (PDT), deltaquattro <deltaquattro@gmail.com> wrote:

-|Hi,
-|
-|the intrinsic sin(x), cos(x), etc, work with arguments of general type
-|and kind type. Suppose I want to write a function mysin(x) which just
-|calls sin(x) and, like sin(x), must work with general type and kind
-|type argument. I can achieve the generality of type through
-|overloading, however how can I obtain generality of kind type?
-|
-|Best regards,
-|
-|deltaquattro

Deltaquattro: About a year ago James Van Buskirk posted an example that you might
find interesting.

See: http://ftp.aset.psu.edu/pub/ger/fort...verloading.f90

Reply With Quote
  #8  
Old 09-04-2008, 01:33 PM
James Van Buskirk
Guest
 
Default Re: How to make a function work with different type and kind type argument

"deltaquattro" <deltaquattro@gmail.com> wrote in message
news:24061886-05c2-4fe7-b3a1-67fae3ac6858@a18g2000pra.googlegroups.com...

> long time no hear sure, I thought of that, but that's not nearly as
> generic as the original sin function. While sin(x) works with any of
> them on any machine, "your" mysin(x) only works with the two KTPs
> Single and Double. Clearly, overloading cannot obtain the same level
> of generality, since even the number of available KTPs varies from
> machine to machine. So, I was wondering how "complete" generality is
> achieved in the intrisic functions, and if this can be replicated by
> user-defined functions.


For the SIN function it's rather awkward to write a generic version
because even after argument reduction the result is obtained by
evaluating a minmax polynomial (actually for SIN perhaps a minmax
polynomial for sin(x)/x) which has different orders for different KINDs.
This means that you would almost have to develop and test different
code for each KIND.

For procedures where the same code works for different KINDs, you can
write a template procedure where the KIND is called something like
'wp' (for Working Precision) and INCLUDE this procedure in various
MODULEs, and USEing those MODULEs in others, perhaps with rename
clauses if you want specific names to be available for the different
versions. I have an example of this in

http://home.comcast.net/~kmbtib/Fort...NERIC_BLAS.ZIP .

This style of template programming will work across user-defined
types or across INTEGER KINDs or across LOGICAL KINDs or across
REAL KINDs, but not on a combination that mixes the above sets.
For this kind of genericity (as for order statistics just to give
one example) we can still achieve template programming but it's
necessary to use implicit typing. The template type now takes
the place of the 'wp' KIND and this means we are limited to no
more than 26 independent template types of this ilk. I have posted
an example at

http://home.comcast.net/~kmbtib/Fortran_stuff/funr1.ZIP .

This issue about not knowing in advance how many KIND types will
be available is insoluble, AFAIK. What I do in my GENERIC_BLAS
example is to write out different versions for the different
numbers of KIND types.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Reply With Quote
  #9  
Old 09-04-2008, 02:14 PM
Craig Powers
Guest
 
Default Re: How to make a function work with different type and kind typeargument

Ron Shepard wrote:
> In article <g9p0s8$iif$1@registered.motzarella.org>,
> Craig Powers <craig.powers@invalid.invalid> wrote:
>
>> deltaquattro wrote:
>>> long time no hear sure, I thought of that, but that's not nearly as
>>> generic as the original sin function. While sin(x) works with any of
>>> them on any machine, "your" mysin(x) only works with the two KTPs
>>> Single and Double. Clearly, overloading cannot obtain the same level
>>> of generality, since even the number of available KTPs varies from
>>> machine to machine. So, I was wondering how "complete" generality is
>>> achieved in the intrisic functions, and if this can be replicated by
>>> user-defined functions.

>> The processors are not actually that general. They know what the total
>> list of available KINDs are, and they provide overloads for all of them.
>> Since there is no possibility of the addition of additional KINDs,
>> they don't need to provide any more generality than that.
>>
>> What Paul suggested is a manual way of achieving the same result.

>
> There may be ways to address these kinds of problems with the new
> levels of abstraction provided by f2008. However, the "traditional"
> way to solve these kinds of portability problems is with
> preprocessors. This works best (or at least it is easiest) when the
> only change required to the code is in the declarations, not in the
> data structures or algorithms. Basically you write a program that
> in turn writes the fortran code. The preprocessor loops over all of
> the allowed types (that you provide as input), it outputs all of the
> different KIND versions of the specific routines, along with the
> interfaces required to have generic functionality. One particularly
> good preprocessor for this kind of stuff is filepp:
>
> http://www.cabaret.demon.co.uk/filepp/
>
> $.02 -Ron Shepard


Alternatively, you can use some sort of generic coding strategy that's
built into the language, which does not yet exist with Fortran but does
with other languages. My point of reference is templates in C++, which
can be very handy to use for code re-use without many of the drawbacks
of preprocessing.
Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 05:43 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.