Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codata constants. #800

Merged
merged 146 commits into from
May 27, 2024
Merged

Codata constants. #800

merged 146 commits into from
May 27, 2024

Conversation

MilanSkocic
Copy link
Contributor

@MilanSkocic MilanSkocic commented Apr 21, 2024

The codata constants are implemented as derived types (#347). This way, the values, the uncertainties and the units are easily available. Only the latest release is implemented i.e. 2018. The 2022 CODATA adjustment are not available yet.

The constants, as provided by the NIST, are double precision reals and I though it was useless to provide to include any other precision.

Your comments and suggestions are welcome.

@jvdp1
Copy link
Member

jvdp1 commented Apr 21, 2024

Thank you @MilanSkocic for this PR.
I am not a user of such constants. So I will add a few possible reviewers.

A general question/comment is about the kinds provided. I think we should try to provide at least single and double precision (it should be easy with fypp). But it is maybe useless (I don't know as I never use such things).

@jvdp1 jvdp1 requested review from certik, ivan-pi, awvwgk, a team and milancurcic April 21, 2024 10:17
@jalvesz
Copy link
Contributor

jalvesz commented Apr 21, 2024

Just a style comment. Maybe instead of defining the actual value of the constants with real(7294.29954142d0,dp) you could simply use 7294.29954142_dp which already declares the kind from the parameter dp, instead of asking for a conversion to the same kind.

@MilanSkocic
Copy link
Contributor Author

MilanSkocic commented Apr 21, 2024

Thank you @MilanSkocic for this PR. I am not a user of such constants. So I will add a few possible reviewers.

A general question/comment is about the kinds provided. I think we should try to provide at least single and double precision (it should be easy with fypp). But it is maybe useless (I don't know as I never use such things).

I have a dedicated repo for generating the constants for the stdlib (https://github.com/MilanSkocic/stdlib_codata) where I have tested single precisions. However, I've got overflows for some constants. I also have my package where I provided codata constants for 2018, 2014 and 2010.

In my point of view single precision are not relevant for the codata constants.

@MilanSkocic
Copy link
Contributor Author

Just a style comment. Maybe instead of defining the actual value of the constants with real(7294.29954142d0,dp) you could simply use 7294.29954142_dp which already declares the kind from the parameter dp, instead of asking for a conversion to the same kind.

Right! I will make the change as soon as possible.

@perazz
Copy link
Contributor

perazz commented Apr 22, 2024

This is a very interesting proposal @MilanSkocic. I have a comment that does not want to mandate any specifications, but just lay out ideas on how this could be made the most productive.

have looked at the state of the art as offered from other well-established packages: Scipy offers a full range of CODATA constants.
They're very easy to use because they're basically just numeric constants. So I think it would be most useful if stdlib could also provide that facility. I think there are two ways to do it:

  1. Implement all overloaded operators (==, /=, >, <, +, -, *, **, /, etc.) so that these parameter derived types can be used exactly as any other real parameter. However, because they also contain units and other information (i.e. error), more tools could be available e.g. something like .approx. to check whether a value is within the uncertainty bounds of the constant.

The drawback is you need to import all operators, not only the constant:

use stdlib_codata, only: ALPHA_PARTICLE_ELECTRON_MASS_RATIO, operator(+), operator(/), assignment(=), ...
  1. Also provide a "macro-like" interface to each of them, so that they can also be used as a real constant in code. for example:
interface gravitational_constant
   module procedure g_sp
   module procedure g_dp
   ...
end interface

!...
elemental real(dp) function g_dp(mold) 
   real(dp), intent(in), optional :: mold ! dp is the default kind
   g_dp = real(NEWTONIAN_CONSTANT_OF_GRAVITATION%value, kind=dp)
end function g_dp

elemental real(dp) function g_sp(mold)
   real(sp), intent(in) :: mold ! sp is not the default kind -> not optional
   g_sp = real(NEWTONIAN_CONSTANT_OF_GRAVITATION%value, kind=sp)
ed function g_sp
!etc.

so one could use them like

real(dp) :: energy = h * gravitational_constant()
real(sp) :: nrg = h * gravitational_constant(mold=0.0)

@jalvesz
Copy link
Contributor

jalvesz commented Apr 22, 2024

Or maybe use the generic facility to avoid having to declare an interface for each constant? like this: https://godbolt.org/z/17qP4TWoa

@perazz
Copy link
Contributor

perazz commented Apr 22, 2024

the generic facility

It's definitely useful if this class has a few methods (including a nice print, etc.). For the purpose of just returning the numeric value (and because there is no constexpr in Fortran), I think a nice named interface is more readable IMHO.
Another option would be to override real and do something like real(NEWTONIAN_CONSTANT_OF_GRAVITATION,kind=dp) which is also Fortranic, but is too long in my opinion

@MilanSkocic
Copy link
Contributor Author

MilanSkocic commented Apr 23, 2024

@perazz You are right, in Scipy, some of the most common physical constants are available directly as reals. They are aliases to the values of the complete list of Codata constants which are implemented as a dictionary where keys are names and items are tuples containing the value, the uncertainty and the unit.
I can implement the codata constants as derived types with the generic facility as suggested by @jalvesz in a module called stdlib_codata and add aliases to the values of the most common physical constants in a module called stdlib_constants as it is done in Scipy. In the latter, mathematical constants, such as PI (#99), could be added later.

An example of using the constants:

program test

! use of the aliases to the values of the most common codata constants and mathematical constants
use stdlib_constants, only: c, PI  

! use of other codata constants
use stdlib_codata, only: ALPHA_PARTICLE_ELECTRON_MASS_RATIO 

real :: b
b = ALPHA_PARTICLE_ELECTRON_MASS_RATIO%eval(b) ! generic facility

end program test

A more advanced use of the stdlib_codata module would allow the user to directly initialize a parameter by accessing the value of the constant.

program test
use stdlib_codata, only: ALPHA_PARTICLE_ELECTRON_MASS_RATIO
use stdlib_kinds, only: dp
real(dp), parameter :: alpha = ALPHA_PARTICLE_ELECTRON_MASS_RATIO%value
end program test

@MilanSkocic
Copy link
Contributor Author

MilanSkocic commented Apr 25, 2024

Update based on suggestions from @perazz and @jalvesz:

  • Generic facility for the codata constants in a dedicated module stdlib_codata_type. The actual auto-generated codata constants are isolated in the module stdlib_codata
  • creation of stdlib_constants where the most common physical constants are aliases to the values of the codata constants (mimic Scipy constant module).
  • Mathematical constants could be added in stdlib_constants ?

src/stdlib_codata_type.fypp Outdated Show resolved Hide resolved
src/stdlib_constants.fypp Show resolved Hide resolved
src/stdlib_constants.fypp Outdated Show resolved Hide resolved
src/stdlib_constants.fypp Outdated Show resolved Hide resolved
@MilanSkocic
Copy link
Contributor Author

MilanSkocic commented Apr 30, 2024

Do I need to create the associated documentation in /docs/specs?
I think that an example would be useful in the example folder. Do you think that a dedicated subfolder constants or codata is necessary or the example can be placed in an already existing subfolder?

@jvdp1
Copy link
Member

jvdp1 commented Apr 30, 2024

Do I need to create the associated documentation in /docs/specs?

Yes, please. It could be called stdlib_constants.md

I think that an example would be useful in the example folder. Do you think that a dedicated subfolder constants or codata is necessary or the example can be placed in an already existing subfolder?

It should be in a dedicated subfolder, e.g., constants.

@MilanSkocic MilanSkocic reopened this Apr 30, 2024
MilanSkocic and others added 19 commits May 21, 2024 08:25
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
@MilanSkocic
Copy link
Contributor Author

MilanSkocic commented May 21, 2024

@jvdp1

  • I implemented the direct comparison in the tests
  • I rebased my code and solved the conflicts

@jvdp1
Copy link
Member

jvdp1 commented May 21, 2024 via email

@MilanSkocic
Copy link
Contributor Author

Do we have an agreement to proceed without any prefix on the constants as they are defined in Scipy? @jvdp1

@jvdp1
Copy link
Member

jvdp1 commented May 24, 2024

Thank you @MilanSkocic
What do you think @perazz @jalvesz @awvwgk ?

@jalvesz
Copy link
Contributor

jalvesz commented May 24, 2024

LGTM!! brilliant work @MilanSkocic

@jvdp1
Copy link
Member

jvdp1 commented May 27, 2024

thank you @MilanSkocic for this PR. I will merge it.

@MilanSkocic Don't hesitate to advertise this new addition on Discourse and other channels.

@jvdp1 jvdp1 merged commit 718ac3a into fortran-lang:master May 27, 2024
17 checks passed
@MilanSkocic
Copy link
Contributor Author

Thank you @jvdp1 ! I'm glad the codata constants have been merged. For sure I'll advertise the addition.
It was a pleasure to contribute to the Fortran-lang community.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants