How would you like to call a NAG routine and have the
precision it computes in determined by the precision of the arguments? So, for
example, your program might contain:
r = s15adf(x,ifail)
If x were single precision then a single precision would be
returned to r. If x were double or quadruple precision then the corresponding
double or quadruple computations would be performed.
I can imagine a number of scenarios where this facility
might be useful, but I invite your comments on how common these might be:- Single precision might be useful as once again single precision calculation becomes faster than double precision. So the user might want to trade accuracy for speed.
- Secondly, single precision used to be the natural interface to many graphics packages. I am not sure whether this is still the case. Would it be useful to have the capability for this reason?
- Double precision, the precision now offered, is generally ‘about right’ for most computations, but sometimes extra precision is needed for the trickiest calculation. Under these circumstances quadruple precision might be necessary. How common is this requirement amongst our users?
- If a computation is made with two different precisions and the resulting answers are broadly similar then a certain level of confidence might be gained from these computations. If on the other hand the results are very different this may indicate that the original problem was ill-conditioned. The ability to do this test easily might be something our
users want. Do you think this is so?
Module dks1
Interface dks
Module Procedure dks_1, dks_2, dks_3
End Interface dks
Contains
Subroutine dks_1(x)
Real (Kind=1) :: x
Print *, 'single precision'
Return
End Subroutine dks_1
Subroutine dks_2(x)
Real (Kind=2) :: x
Print *, 'double precision'
Return
End Subroutine dks_2
Subroutine dks_3(x)
Real (Kind=3) :: x
Print *, 'quadruple precision'
Return
End Subroutine dks_3
End Module dks1
Program main
Use dks1
Real (Kind=1) :: x1
Real (Kind=2) :: x2
Real (Kind=3) :: x3
Call dks(x1)
Call dks(x2)
Call dks(x3)
Stop 'ok'
End Program main
(Here the Kind convention is the natural one for the NAG Compiler; others might use a ‘Byte convention’ i.e. the kind number matches the number of bytes of storage. Thus some compilers use ‘Real (Kind=4)’ to denote single precision and ‘Real (Kind = 8)’ to denote double precision.
Interface dks
Module Procedure dks_1, dks_2, dks_3
End Interface dks
Contains
Subroutine dks_1(x)
Real (Kind=1) :: x
Print *, 'single precision'
Return
End Subroutine dks_1
Subroutine dks_2(x)
Real (Kind=2) :: x
Print *, 'double precision'
Return
End Subroutine dks_2
Subroutine dks_3(x)
Real (Kind=3) :: x
Print *, 'quadruple precision'
Return
End Subroutine dks_3
End Module dks1
Program main
Use dks1
Real (Kind=1) :: x1
Real (Kind=2) :: x2
Real (Kind=3) :: x3
Call dks(x1)
Call dks(x2)
Call dks(x3)
Stop 'ok'
End Program main
(Here the Kind convention is the natural one for the NAG Compiler; others might use a ‘Byte convention’ i.e. the kind number matches the number of bytes of storage. Thus some compilers use ‘Real (Kind=4)’ to denote single precision and ‘Real (Kind = 8)’ to denote double precision.
My implementation colleagues will point out that instead of checking over 3000 results per implementation they would have over 9000 if we were to provide this capability. How appreciative would our users be if we were to do this? I am sure that I wouldn't manage to convince my colleagues to take on this extra work without evidence that our customers would like it. So if you think this is worthwhile then please let us know.