From: Richard Maine on
steve <kargls(a)comcast.net> wrote:

> I do note that Glen has point
> out that DCOS is needed for passing a specific cosine function to
> a subprogram as an actual argument.

And I've wanted to do that... let's count... that would be exactly zero
times in over 40 years of programming. Maybe by 50 years I'l hit one,
but I doubt it. The few specific intrinsics you can do that with just
don't turn out to be ones that tend to be the ones that usually want to
get passed as actual arguments in real applications. I suppose I can
imagine passing dcos as an actual argument for something like testing
purposes (say to test an integration routine), but that does't count as
a real application. (If you are numerically integrating dcos in a real
algorithm, we need to talk :-)). And sure, I can invent some artificial
situation, but I've never been in one for real. Glen implied similar
things, though less emphatically than I am doing.

Note that even then, it isn't "needed", but is just a convenience. If
you really wanted the functionality of dcos passed as an actual
argument, you could write your own

function my_dcos(x)
integer :: dp = kind(1.0d0) !-- Or USE an appropriate module
real(dp), intent(in) :: x
real(dp) :: my_dcos
my_dcos = cos(x)
return
end

which you could then pass as the actual argument. Sure that adds a
little overhead, but considering the overhead already involved in
invoking functions passed as actual arguments, and considering the
number of times you are ever going to want anything like this (zero so
far for me), that's not likely to be much of an issue.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: robin on
<analyst41(a)hotmail.com> wrote in message news:4e146215-d595-42f7-af9e-faa2fd1fe4e5(a)a7g2000yqo.googlegroups.com...
| (1) Using Double Precision for latitude and longitude and using double
| precision for degrees to radians and radius of the earth (by the way,
| I have seen values that differ by about 4 miles)

If you are getting inaccuracies, perghaps you should look for other
causes.
The most likely of those is constants being taken as single precision
where you were assuming that they were double precision.

Note that it is necessary to use the double precision form
of constants such as 1.234D0 (1.234 is taken as single precision),
where double precision is needed.


From: James Van Buskirk on
"Richard Maine" <nospam(a)see.signature> wrote in message
news:1j7na7d.92wynv1cis7piN%nospam(a)see.signature...

> Note that even then, it isn't "needed", but is just a convenience. If
> you really wanted the functionality of dcos passed as an actual
> argument, you could write your own

> function my_dcos(x)
> integer :: dp = kind(1.0d0) !-- Or USE an appropriate module
> real(dp), intent(in) :: x
> real(dp) :: my_dcos
> my_dcos = cos(x)
> return
> end

> which you could then pass as the actual argument. Sure that adds a
> little overhead, but considering the overhead already involved in
> invoking functions passed as actual arguments, and considering the
> number of times you are ever going to want anything like this (zero so
> far for me), that's not likely to be much of an issue.

We can force it to be necessary.

C:\gfortran\clf\dcos>type dcos.f90
module funcs
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
! function my_dcos(x)
elemental function my_dcos(x)
! integer :: dp = kind(1.0d0) !-- Or USE an appropriate module
integer, parameter :: dp = kind(1.0d0) !-- Or USE an appropriate module
real(dp), intent(in) :: x
real(dp) :: my_dcos
my_dcos = cos(x)
return
! end
end function
subroutine test(fun)
interface
elemental function fun(x)
import
implicit none
real(dp), intent(in) :: x
real(dp) fun
end function fun
end interface
real(dp) x(3)
x = [1,2,3]
write(*,*) fun(x)
end subroutine test
end module funcs

program start
use funcs
implicit none
call test(my_dcos)
end program start

C:\gfortran\clf\dcos>gfortran -Wall dcos.f90 -odcos
dcos.f90:33.13:

call test(my_dcos)
1
Error: ELEMENTAL non-INTRINSIC procedure 'my_dcos' is not allowed as an
actual a
rgument at (1)

So we can fix this:

C:\gfortran\clf\dcos>type dcos.f90
module funcs
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
function my_dcos(x)
! elemental function my_dcos(x)
! integer :: dp = kind(1.0d0) !-- Or USE an appropriate module
integer, parameter :: dp = kind(1.0d0) !-- Or USE an appropriate module
real(dp), intent(in) :: x
real(dp) :: my_dcos
my_dcos = cos(x)
return
! end
end function
subroutine test(fun)
interface
elemental function fun(x)
import
implicit none
real(dp), intent(in) :: x
real(dp) fun
end function fun
end interface
real(dp) x(3)
x = [1,2,3]
write(*,*) fun(x)
end subroutine test
end module funcs

program start
use funcs
implicit none
call test(my_dcos)
end program start

C:\gfortran\clf\dcos>gfortran -Wall dcos.f90 -odcos

C:\gfortran\clf\dcos>dcos
0.54030230586813976 -0.41614683654714241 -0.98999249660044542

But now...

C:\gfortran\clf\dcos>ifort dcos.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.

dcos.f90(33) : Error: Procedure argument must be PURE [MY_DCOS]
call test(my_dcos)
-------------^
dcos.f90(33) : Error: The PURE attribute of the associated actual procedure
diff
ers from the PURE attribute of the dummy procedure. [MY_DCOS]
call test(my_dcos)
-------------^
dcos.f90(33) : Error: The ELEMENTAL attribute of the associated actual
procedure
differs from the ELEMENTAL attribute of the dummy procedure. [MY_DCOS]
call test(my_dcos)
-------------^
compilation aborted for dcos.f90 (code 1)

Of course I think this restriction from f95 is silly, but I don't
think it has been changed as of f08, see N1723.pdf, C1234.

Now with DCOS, all this just works:

C:\gfortran\clf\dcos>type dcos.f90
module funcs
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
function my_dcos(x)
! elemental function my_dcos(x)
! integer :: dp = kind(1.0d0) !-- Or USE an appropriate module
integer, parameter :: dp = kind(1.0d0) !-- Or USE an appropriate module
real(dp), intent(in) :: x
real(dp) :: my_dcos
my_dcos = cos(x)
return
! end
end function
subroutine test(fun)
interface
elemental function fun(x)
import
implicit none
real(dp), intent(in) :: x
real(dp) fun
end function fun
end interface
real(dp) x(3)
x = [1,2,3]
write(*,*) fun(x)
end subroutine test
end module funcs

program start
use funcs
implicit none
intrinsic dcos
! call test(my_dcos)
call test(dcos)
end program start

C:\gfortran\clf\dcos>gfortran -Wall dcos.f90 -odcos

C:\gfortran\clf\dcos>dcos
0.54030230586813976 -0.41614683654714241 -0.98999249660044542

C:\gfortran\clf\dcos>ifort dcos.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.

dcos.f90(35) : Error: Procedure argument must be PURE [DCOS]
call test(dcos)
-------------^
compilation aborted for dcos.f90 (code 1)

See? Works perfect, even down to exposing a bug in an admittedly
old version of ifort.

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


From: James Van Buskirk on
"Jan Gerrit Kootstra" <jan.gerrit(a)kootstra.org.uk> wrote in message
news:16ac1$4ad8025c$4df909b6$1677(a)news.chello.nl...

> James,

> I never called a function, only assigned it to a variable.
> So is it a bug in ifort or a feature in gfortran?

Since you have not posted previously in this thread I will assume
that you are talking about my [elided] example, just not perhaps
expressing yourself clearly.

In that case, the example where the DCOS intrinsic was the actual
argument associated with an elemental dummy argument was standard-
conforming. Actually ifort's behavior is a bug in a feature of
ifort. That compiler seems to me to build data structures that
keep better track of whether procedure arguments match their
interfaces. If you don't keep track as well as ifort, you don't
always catch when a dummy argument is PURE and the actual argument
is not. You also don't encounter bugs where the compiler misses
the fact that intrinsic procedures are mostly elemental (with most
of the exceptions being transformational or inquiry) but ifort
accepts that risk because procedure mismatch is one of the
commonest 'hard' bugs to squash and the compiler has been good at
detecting it since the DVF days at least.

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


From: Arjan on
On 16 okt, 03:08, analys...(a)hotmail.com wrote:
> (1) Using Double Precision for latitude and longitude and using double
> precision for degrees to radians and radius of the earth (by the way,
> I have seen values that differ by about 4 miles)
> (2) checking argument of acos to be between -1 and 1



1: ACOS is not a good choice for this type of problem.
Try to make a Taylor series around +/- 1. That will fail
since the function is infinitely steep. The same feature
will give numerical imprecision in the neighbourhood of +/- 1.

Solution: Apart from constructing COS(theta) and COS(phi), please
also
construct SIN(theta) and SIN(phi) and then use ATAN2 to get your
angles,
not just ACOS.

2: If you are really interested in geodesics: the earth is not a
sphere.
Get the (free) Proj4 library, compile it and use that to estimate
distances.
That package models the earth as an ellipsoid and knows how to
deal
with distances.

Regards,


Arjan