Home > Archive > Fortran > September 2005 > How to test minimum value argument to EXP
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
How to test minimum value argument to EXP
|
|
| Herman D. Knoble 2005-09-13, 6:59 pm |
| What is an efficient way of determining a minumum value of
the argument to EXP, for any given platform/compiler?
For example, how can the value of MinValue in the following
code be computed efficiently (without the LOG function)?
Program ExpTest
integer, parameter :: pr = selected_real_kind(15)
real (kind=pr) :: x, y, MinValue
! How (without log function) can one determine MinValue
! such that any number x < MinValue causes EXP function
! to underflow (return zero), but x = MinValue does not
! cause EXP function to underflow.
!
! Trial Value of MinValue = 200
MinValue = 200
read *, x
! Prevent underflow
if (x < MinValue) then
y=0
else
y=exp(x)
end if
print *, "x,y=",x,y
End Program
| |
| beliavsky@aol.com 2005-09-13, 6:59 pm |
| Herman D. Knoble wrote:
> What is an efficient way of determining a minumum value of
> the argument to EXP, for any given platform/compiler?
>
> For example, how can the value of MinValue in the following
> code be computed efficiently (without the LOG function)?
>
>
> Program ExpTest
>
> integer, parameter :: pr = selected_real_kind(15)
> real (kind=pr) :: x, y, MinValue
>
> ! How (without log function) can one determine MinValue
> ! such that any number x < MinValue causes EXP function
> ! to underflow (return zero), but x = MinValue does not
> ! cause EXP function to underflow.
> !
> ! Trial Value of MinValue = 200
> MinValue = 200
>
> read *, x
>
> ! Prevent underflow
> if (x < MinValue) then
> y=0
> else
> y=exp(x)
> end if
>
> print *, "x,y=",x,y
>
> End Program
To check for UNDERFLOW of exp(x), shouldn't the trial value of x be
-200 rather than 200?
| |
| Herman D. Knoble 2005-09-13, 6:59 pm |
|
Sorry. Make that:
! Trial Value of MinValue = -700
MinValue = -700
below.
On Tue, 13 Sep 2005 14:08:36 -0400, Herman D. Knoble <SkipKnobleLESS@SPAMpsu.DOT.edu>
wrote:
-|What is an efficient way of determining a minumum value of
-|the argument to EXP, for any given platform/compiler?
-|
-|For example, how can the value of MinValue in the following
-|code be computed efficiently (without the LOG function)?
-|
-|
-| Program ExpTest
-|
-| integer, parameter :: pr = selected_real_kind(15)
-| real (kind=pr) :: x, y, MinValue
-|
-|! How (without log function) can one determine MinValue
-|! such that any number x < MinValue causes EXP function
-|! to underflow (return zero), but x = MinValue does not
-|! cause EXP function to underflow.
-|!
-|! Trial Value of MinValue = 200
-| MinValue = 200
-|
-| read *, x
-|
-|! Prevent underflow
-| if (x < MinValue) then
-| y=0
-| else
-| y=exp(x)
-| end if
-|
-| print *, "x,y=",x,y
-|
-| End Program
-|
| |
|
| Hi, maybe you can try: log(tiny(1.0d0))
In my machine it is -708.396418532264.
But trying different numbers bellow -708, I reached -745 as the minimal
value where I got something different to 0 when applying exp. But log
tiny is close enough to try to loop until you reach it.
Conclusion: it is a good guess.
FJRA
| |
| Richard E Maine 2005-09-13, 6:59 pm |
| In article <9a3ei1tv3b3le4sgbfn590t8thhpgqjdmh@4ax.com>,
Herman D. Knoble <SkipKnobleLESS@SPAMpsu.DOT.edu> wrote:
> What is an efficient way of determining a minumum value of
> the argument to EXP, for any given platform/compiler?
>
> For example, how can the value of MinValue in the following
> code be computed efficiently (without the LOG function)?
I don't really understand the restriction against using LOG. Seems to me
that most of the "obvious" methods involve using a logarithm of some
form or other somewhere along the line. One can, of course, invert the
exp function by any number of means, both simple and not so simple, but
those just amount to roundabout ways of computing a logarithm. I'm also
a little surprised that efficiency in such a thing would matter, as the
result could be computed once and saved. If this is in something to be
invoked zillions of times, then the efficiency saving from doing the
computation just once would probably dwarf any algorithm tweaks.
You could probably get a fast rough answer by twiddling with the result
of the minexponent() intrinsic. I haven't bothered to figure out the
exact twiddle, but it shouldn't take long to do so. That is, in essence,
just one way to do a quick hack at a logarithm.
In any case, be aware that a precise answer is going to depend on
command-line (or run-time settable) options on many compilers. In
particular, it is common to have options to control whether underflow is
gradual or abrupt. If you want to be sensitive enough to detect that
distinction, then a bit further work would probably be needed. I can't
think of a completely portable and accurate way to do it that doesn't
involve a search. After all, any completely portable and accurate way
would have to give different results depending on the setting of the
gradual underflow option, so anything based solely on the numeric
inquiry intrinsics would be right out (though they could give you a good
starting point for the search).
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| glen herrmannsfeldt 2005-09-13, 6:59 pm |
| Herman D. Knoble wrote:
> What is an efficient way of determining a minumum value of
> the argument to EXP, for any given platform/compiler?
> For example, how can the value of MinValue in the following
> code be computed efficiently (without the LOG function)?
I would say binary search, though you need an upper and
lower bound to do that.
The upper bound could be zero. If it returns fast with large
negative values it probably doesn't matter too much.
Here it is in awk, you can do it about as easy in Fortran.
Awk nicely prints a message for every out of range argument.
-- glen
BEGIN {
u=0;
l=-1000000;
# choose the following constant carefully depending
# on the precision of the variables you are using.
while(u>l+.0000001) {
x=(u+l)/2;
y=exp(x);
if(y==0) l=x;
else u=x;
}
printf "%20.14e\n",x;
}
| |
| Herman D. Knoble 2005-09-13, 6:59 pm |
| Richard: Now that you made me think (again), I agree with you.
Thanks.
Skip
On Tue, 13 Sep 2005 12:03:30 -0700, Richard E Maine <nospam@see.signature> wrote:
-|In article <9a3ei1tv3b3le4sgbfn590t8thhpgqjdmh@4ax.com>,
-| Herman D. Knoble <SkipKnobleLESS@SPAMpsu.DOT.edu> wrote:
-|
-|> What is an efficient way of determining a minumum value of
-|> the argument to EXP, for any given platform/compiler?
-|>
-|> For example, how can the value of MinValue in the following
-|> code be computed efficiently (without the LOG function)?
-|
-|I don't really understand the restriction against using LOG. Seems to me
-|that most of the "obvious" methods involve using a logarithm of some
-|form or other somewhere along the line. One can, of course, invert the
-|exp function by any number of means, both simple and not so simple, but
-|those just amount to roundabout ways of computing a logarithm. I'm also
-|a little surprised that efficiency in such a thing would matter, as the
-|result could be computed once and saved. If this is in something to be
-|invoked zillions of times, then the efficiency saving from doing the
-|computation just once would probably dwarf any algorithm tweaks.
-|
-|You could probably get a fast rough answer by twiddling with the result
-|of the minexponent() intrinsic. I haven't bothered to figure out the
-|exact twiddle, but it shouldn't take long to do so. That is, in essence,
-|just one way to do a quick hack at a logarithm.
-|
-|In any case, be aware that a precise answer is going to depend on
-|command-line (or run-time settable) options on many compilers. In
-|particular, it is common to have options to control whether underflow is
-|gradual or abrupt. If you want to be sensitive enough to detect that
-|distinction, then a bit further work would probably be needed. I can't
-|think of a completely portable and accurate way to do it that doesn't
-|involve a search. After all, any completely portable and accurate way
-|would have to give different results depending on the setting of the
-|gradual underflow option, so anything based solely on the numeric
-|inquiry intrinsics would be right out (though they could give you a good
-|starting point for the search).
| |
| Herman D. Knoble 2005-09-13, 6:59 pm |
| FJRA: Thank you. This is exactly what I was looking for
even mistakenly (see Richard's posting) indicated "without
using log".
Again, thanks.
Skip
On 13 Sep 2005 11:56:57 -0700, "FJRA" <a19980403@pucp.edu.pe> wrote:
-|Hi, maybe you can try: log(tiny(1.0d0))
-|In my machine it is -708.396418532264.
-|But trying different numbers bellow -708, I reached -745 as the minimal
-|value where I got something different to 0 when applying exp. But log
-|tiny is close enough to try to loop until you reach it.
-|Conclusion: it is a good guess.
-|
-| FJRA
| |
| glen herrmannsfeldt 2005-09-13, 6:59 pm |
| Richard E Maine wrote:
> In article <9a3ei1tv3b3le4sgbfn590t8thhpgqjdmh@4ax.com>,
> Herman D. Knoble <SkipKnobleLESS@SPAMpsu.DOT.edu> wrote:
[color=darkred]
> I don't really understand the restriction against using LOG. Seems to me
> that most of the "obvious" methods involve using a logarithm of some
> form or other somewhere along the line. One can, of course, invert the
> exp function by any number of means, both simple and not so simple, but
> those just amount to roundabout ways of computing a logarithm.
Software exp() usually have a test near the beginning, and I thought
he wanted to find the value for that test. It is likely at least
slightly different than the minimum value returned by log().
> I'm also
> a little surprised that efficiency in such a thing would matter, as the
> result could be computed once and saved. If this is in something to be
> invoked zillions of times, then the efficiency saving from doing the
> computation just once would probably dwarf any algorithm tweaks.
Well, if he was doing linear search I can see asking for a more
efficient way. Binary search gets there pretty fast, though maybe
10 or 20 times slower than log(), depending on how accurate the
result needs to be.
> You could probably get a fast rough answer by twiddling with the result
> of the minexponent() intrinsic. I haven't bothered to figure out the
> exact twiddle, but it shouldn't take long to do so. That is, in essence,
> just one way to do a quick hack at a logarithm.
> In any case, be aware that a precise answer is going to depend on
> command-line (or run-time settable) options on many compilers. In
> particular, it is common to have options to control whether underflow is
> gradual or abrupt. If you want to be sensitive enough to detect that
> distinction, then a bit further work would probably be needed. I can't
> think of a completely portable and accurate way to do it that doesn't
> involve a search. After all, any completely portable and accurate way
> would have to give different results depending on the setting of the
> gradual underflow option, so anything based solely on the numeric
> inquiry intrinsics would be right out (though they could give you a good
> starting point for the search).
If you have a bad starting point it costs about log(-starting point)
extra cycles. Also, about one cycle per bit of accuracy needed.
Fast enough for me, anyway.
-- glen
| |
| Tim Prince 2005-09-13, 9:56 pm |
| Richard E Maine wrote:
> After all, any completely portable and accurate way
> would have to give different results depending on the setting of the
> gradual underflow option, so anything based solely on the numeric
> inquiry intrinsics would be right out (though they could give you a good
> starting point for the search).
>
If abrupt underflow
log(tiny(1d0))
else
log(tiny(1d0)) + log(epsilon(1d0))
+ whatever allowance for error you think necessary for "portability."
| |
| Richard Maine 2005-09-14, 7:57 am |
| In article <eGLVe.582$7x4.93@newssvr13.news.prodigy.com>,
Tim Prince <tprince@nospamcomputer.org> wrote:
> Richard E Maine wrote:
> If abrupt underflow
> log(tiny(1d0))
> else
> log(tiny(1d0)) + log(epsilon(1d0))
>
> + whatever allowance for error you think necessary for "portability."
The "if abrupt underflow" part is one of the posibilities I was
referring to that isn't based solely on the numeric inquiry intrinsics,
since there isn't a (standard) intrinsic for that... in f95 anyway.
Might be one in the IEEE stuff of f2003; I don't recall for sure and am
about to head of to bed - not inclined to go check right now.
| |
| Jan Vorbrüggen 2005-09-14, 7:57 am |
| > If abrupt underflow
> log(tiny(1d0))
> else
> log(tiny(1d0)) + log(epsilon(1d0))
However, even when demormalized numbers are enabled - i.e., abrupt under-
flow is false - you might want to consider avoiding them: in many systems,
arithmetic that have at least one denormalized number as input is emulated,
which leads to a substantial performance loss. Disabling gradual underflow
on an UltraSPARC system in an application doing convolutions via FFTs im-
proved performance by as much as a _factor_ of 20 for some of them, and
fully removed variability.
Jan
| |
| Tim Prince 2005-09-14, 7:57 am |
| Richard Maine wrote:
> In article <eGLVe.582$7x4.93@newssvr13.news.prodigy.com>,
> Tim Prince <tprince@nospamcomputer.org> wrote:
>
>
>
>
> The "if abrupt underflow" part is one of the posibilities I was
> referring to that isn't based solely on the numeric inquiry intrinsics,
> since there isn't a (standard) intrinsic for that... in f95 anyway.
> Might be one in the IEEE stuff of f2003; I don't recall for sure and am
> about to head of to bed - not inclined to go check right now.
If I understand what is written by Metcalf, Reid, and Cohen
use,intrinsic :: ieee_arithmetic
call ieee_get_underflow_mode(gradual)
if(gradual)then......
| |
| Tim Prince 2005-09-14, 7:00 pm |
| Jan Vorbrüggen wrote:
>
>
> However, even when demormalized numbers are enabled - i.e., abrupt under-
> flow is false - you might want to consider avoiding them: in many systems,
> arithmetic that have at least one denormalized number as input is emulated,
> which leads to a substantial performance loss. Disabling gradual underflow
> on an UltraSPARC system in an application doing convolutions via FFTs im-
> proved performance by as much as a _factor_ of 20 for some of them, and
> fully removed variability.
>
> Jan
In support of the benchmarking wars, the trend appears to be toward
defaulting to abrupt underflow, at least where Microsoft has influence.
I don't suppose system vendors would dare to justify this on the basis
that Fortran software might be written portably to set the desired mode,
as they could then be challenged to implement that part of f2003.
| |
| Rich Townsend 2005-09-14, 7:00 pm |
| Jan Vorbrüggen wrote:
>
>
> However, even when demormalized numbers are enabled - i.e., abrupt under-
^^^^^^^^^^^^
I read this as 'demoralized'. How does one trap a number mutiny? Sounds like
something Intercal would be good at!
cheers,
Rich
|
|
|
|
|