From: Richard Maine on 15 Oct 2009 23:44 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 15 Oct 2009 23:42 <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 16 Oct 2009 01:01 "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 16 Oct 2009 01:43 "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 16 Oct 2009 03:41 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
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Integer return values in interfaces Next: Cannot mex with gfortran on Snow Leopard (64bit) |