Skip to content

Intrinsics for mathematical constants #240

@ivan-pi

Description

@ivan-pi

This issue originates from one of the questions at the HPFPC (High-Performance computing with Fortran Promoting Consortium) symposium (https://site.hpfpc.org/home/events/parallel_fortran_sympo5)

In the requests & questions list we can read

Q27: The standard should include some physical constants such as pi. It is more helpful if they can used without using any modules, similarly to intrinsic procedures.

A27: This would not be a big addition to the language, but it has not been requested.

This has also been suggested and discussed at length in one of the stdlib issues: fortran-lang/stdlib#99

Current status

In most Fortran codes today, users rely upon statements like:

real(wp), parameter :: pi = 4*atan(1.0_wp) ! or
real(wp), parameter :: pi = 2*acos(0.0_wp)
real(wp), parameter :: e = exp(1.0_wp)

that are collected in a constants module, leading to duplication of effort and potential errors.

Personally, I often re-declare pi locally in each module (to lazy to use a module) and find myself wondering which trigonometric function am I supposed to use in my head or drawing a unit circle on a sheet of paper.

Other programming languages

Other languages are also known to provide such constants, e.g. in C the header file math.h provides the following:

  • M_E: The base of natural logarithms.
  • M_LOG2E: The logarithm to base 2 of M_E.
  • M_LOG10E: The logarithm to base 10 of M_E.
  • M_LN2: The natural logarithm of 2.
  • M_LN10: The natural logarithm of 10.
  • M_PI: Pi, the ratio of a circle’s circumference to its diameter.
  • M_PI_2: Pi divided by two.
  • M_PI_4: Pi divided by four.
  • M_1_PI: The reciprocal of pi (1/pi).
  • M_2_PI: Two times the reciprocal of pi.
  • M_2_SQRTPI: Two times the reciprocal of the square root of pi.
  • M_SQRT2: The square root of two.
  • M_SQRT1_2: The reciprocal of the square root of two (also the square root of 1/2).

Julia also provides the constants for im (imaginary unit), pi, (the constant ℯ), Catalan's constant, Euler's constant, and the golden ratio, among others.

Python provides math.pi, math.e, and math.tau (2 times pi) to available precision (presumably C double in most implementations).

Solution

The solution could be provided in terms of intrinsic functions, e.g.

pure function math_pi(kind) real(pi)
   integer, kind :: kind  ! not valid Fortran
   real(kind=kind) :: pi

which accept an integer kind argument. This is still kind of verbose, but users can always use a parameter:

real(wp), parameter :: pi = math_pi(wp)

or an associate construct:

associate(pi => math_pi(wp), e => math_e(wp))
...
end associate

if they want a shorter variable name.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Clause 16Standard Clause 16: Intrinsic procedures and modules

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions