From: Richard Maine on
Stormin <norman.kirkby(a)gmail.com> wrote:

> can the elemental procedure appear inside a module which handles
> errors at the level of the module?

No.

> The following is not working fortran but gives my idea
[code elided]

That trivially violates on of the most fundamental properties of a pure
(and thus elemental) procedure. Pure procedures cannot have side
effects. Ok, the definition of "side effect" can be tricky (I have heard
people suggest that consuming CPU time is a side effect), but I'm just
using that as a broad general description here. The standard is a lot
more specific and precise about this one, which is one of the most
straightforward cases. In particular, you can't change the value of a
variable accessed via host association (or ay other way of getting at
"outside" variables, but host association is the one used here and one
that is specifically prohibitted in the standard).

My general description of prohibitting side effects is to give you a
conceptual context to keep from wasting time looking for other ways to
achieve a simillar effect. If you manage to find one, that would
probably be a bug in the standard; prohibition of such things is the
idea.

Like most of the requirements on pure procedures, this one is a
constraint, which means that compilers are required to be able to
diagnose it.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Harald Anlauf on
On Jan 9, 6:07 pm, Stormin <norman.kir...(a)gmail.com> wrote:
> A function in the module can report the exact nature of the error.
> Does this rather long winded approach violate the concept of an
> elemental procedure?

Yes, this is illegal, as Richard pointed out. If you want a separate
error status, you must use a subroutine.

Here is a working example:

module my_sqrt
implicit none
contains
elemental subroutine calc_my_sqrt (x, y, stat)
real, intent(in) :: x
real, intent(out) :: y
integer, intent(out) :: stat
if(x.lt. 0.0)then
stat = 1
y = -HUGE (x)
else
stat = 0
y = sqrt (x)
endif
end subroutine calc_my_sqrt
end module my_sqrt

program test
use my_sqrt
implicit none
integer, parameter :: N = 5
real, dimension(N) :: y, z
integer, dimension(N) :: status
integer :: errloc

call random_number (z)
call calc_my_sqrt (x=z, y=y, stat=status)
if (any (status /= 0)) then
errloc = maxloc (status, dim=1)
print *, "Error: the following argument was illegal:", z(errloc)
endif
print *, y
end program test


You may modify one element of the argument z to see how error handling
works.

Harald
From: Reinhold Bader on
Since the OP's question was rather general in scope, I'd like to
comment that the below is not true if you take derived types into
consideration.

By adding an extra component which indicates the validity of an
entity to a type definition

type :: foo
: ! whatever data I need
integer :: status = 0
end type

(plus a set of constants describing the needed kinds of stati) it
is clearly possible to write elemental subroutines or even functions
which use entities of type(foo) as arguments or function results,
without introducing side effects.
Clearly, separate checking for each array element (if the actual
argument is an array entity) is still required - something along the
lines of

if (any(obj_foo%status /= status_ok)) then
! perform error treatment
end if

Regards,

Reinhold

Am 09.01.2010 18:52, schrieb Harald Anlauf:
> On Jan 9, 6:07 pm, Stormin <norman.kir...(a)gmail.com> wrote:
>> A function in the module can report the exact nature of the error.
>> Does this rather long winded approach violate the concept of an
>> elemental procedure?
>
> Yes, this is illegal, as Richard pointed out. If you want a separate
> error status, you must use a subroutine.
>
> Here is a working example:
>
> module my_sqrt
> implicit none
> contains
> elemental subroutine calc_my_sqrt (x, y, stat)
> real, intent(in) :: x
> real, intent(out) :: y
> integer, intent(out) :: stat
> if(x.lt. 0.0)then
> stat = 1
> y = -HUGE (x)
> else
> stat = 0
> y = sqrt (x)
> endif
> end subroutine calc_my_sqrt
> end module my_sqrt
>
> program test
> use my_sqrt
> implicit none
> integer, parameter :: N = 5
> real, dimension(N) :: y, z
> integer, dimension(N) :: status
> integer :: errloc
>
> call random_number (z)
> call calc_my_sqrt (x=z, y=y, stat=status)
> if (any (status /= 0)) then
> errloc = maxloc (status, dim=1)
> print *, "Error: the following argument was illegal:", z(errloc)
> endif
> print *, y
> end program test
>
>
> You may modify one element of the argument z to see how error handling
> works.
>
> Harald

From: glen herrmannsfeldt on
Ron Shepard <ron-shepard(a)nospam.comcast.net> wrote:
> In article <4B4872FC.2060706(a)net-b.de>,
> Tobias Burnus <burnus(a)net-b.de> wrote:

>> IEEE Std. 754:2008 has:
>
>> "The operation squareRoot(x) computes ???x [= sqrt(x)]. It has a positive
>> sign for all operands >= 0, except that squareRoot(-0) shall be -0.The
>> preferred exponent is floor(Q(x) / 2)."

> At the risk of following an off-topic tangent, what exactly does
> that last sentence mean. Are there IEEE floating point numbers that
> can be represented with more than one exponent?

My understanding is that it relates to rounding. Since the exponent
changes at integer values, it seems that means that
sqrt(3.99999999) should not be, for example, 2.00000001 and
sqrt(4.00000001) should not be, for example, 1.99999999

-- glen
From: steve on
On Jan 9, 11:56 am, glen herrmannsfeldt <g...(a)ugcs.caltech.edu> wrote:
> Ron Shepard <ron-shep...(a)nospam.comcast.net> wrote:
> > In article <4B4872FC.2060...(a)net-b.de>,
> > Tobias Burnus <bur...(a)net-b.de> wrote:
> >> IEEE Std. 754:2008 has:
>
> >> "The operation squareRoot(x) computes ???x [= sqrt(x)]. It has a positive
> >> sign for all operands >= 0, except that squareRoot(-0) shall be -0.The
> >> preferred exponent is floor(Q(x) / 2)."
> > At the risk of following an off-topic tangent, what exactly does
> > that last sentence mean.  Are there IEEE floating point numbers that
> > can be represented with more than one exponent?
>
> My understanding is that it relates to rounding.  Since the exponent
> changes at integer values, it seems that means that
> sqrt(3.99999999) should not be, for example, 2.00000001 and
> sqrt(4.00000001) should not be, for example, 1.99999999

Not likely for sqrt() with base 2 floating point. I only have the
final committee draft of the new IEEE 754 standard. It states

The squareRoot operation is defined and has a positive sign for
all operands greater or equal to 0, except that squareRoot(–0)
shall be –0. For inexact decimal results, the preferred exponent
is the least possible. For exact decimal results, the preferred
exponent is floor(Q(x) / 2).

If Tobias quoted the ratified standard, then the language has changed.
For base 2 floating point, sqrt() can be correctly rounded in all
rounding modes. The draft further states

For certain computational operations, if the result is inexact,
the cohort member of least possible exponent is used to get the
longest possible significand; if the result is exact, the cohort
member is selected based on the preferred exponent for a result
of that operation, a function of the exponents of the inputs.

For other computational operations, whether or not the result is
exact, the cohort member is selected based on the preferred
exponent
for a result of that operation. Thus for finite x, depending on
the
representation of zero, 0 + x might result in a different member
of x’s cohort.

If the result’s cohort does not include a member with the
preferred
exponent, the member with the exponent closest to the preferred
exponent is used.

In the descriptions that follow, Q(x) is the exponent q of the
representation of a finite floating-point number x. If x is
infinite,
Q(x) is +∞.

Without digging deeper, I suspect that this prevents unnormal numbers.

--
steve