For Programmers: Free Programming Magazines  


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
-|

FJRA

2005-09-13, 6:59 pm

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
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com