I propose that we provide a module with miscellaneous mathematical functions, those which feel like they could/should be intrinsics, but are not for whatever reason. From my own experience, here are functions which I have felt the need to implement myself several times:
expm1(x) and log1p(x) - I suspect that many compilers detect exp(x) - 1.0/log(1.0 + x) and call appropriate library routines, but I'd like to provide these explicitly.signum(x) - The intrinsic sign function is awkward to use when you just want to know the sign of a number. cbrt(x) - Again, I suspect many compilers detect x**(1.0/3.0) and call into their math library's cbrt. However, real exponents are ugly and error-prone and would like a more semantic replacement for this common case.sinc(x) - I am tired of writing my own implementation of this, and I suspect others are as well, even if it is trivial.phase(z) - Equivalent to atan2(z%im, z%re) Let's brainstorm further functionality that you'd like to see.
I agree, these would be all useful. Compilers should detect exp(x) - 1 and log(1 + x) and do the right thing, but it cannot hurt to have those functions explicitly.
Actually, sinc is not completely trivial. Here is the implementation that I use:
real(dp) elemental function sinc(x) result(r)
real(dp), intent(in) :: x
if (abs(x) < 1e-8_dp) then
r = 1
else
r = sin(x)/x
end if
end function
For high accuracy once must fine tune the cutoff, I ended up with 1e-8, but we would need to test this and ensure we are getting ~1e-15 accuracy for all x.
Some more worth considering:
z*log(z) and log(z)/z which give the correct behavior near z=0. Not sure of good names.Some with a distinctly statistical flavor, which maybe belong in the stats module:
logit(x) for evaluating log(x)/log(1-x)logistic(x) for evaluating exp(x)/[1 + exp(x)] (the function whose inverse is logit)logsumexp(x) for evaluating log(sum(exp(x))) with x being an array. Would the factorial and the binomial coefficient belong to this too?
What about:
cumprod)cumsum)They would be probably in another module since they would not be elemental.
If a ”math” module is reserved for the elemental functions, Perhaps cumsum cumprod etc. Could go in a “numerical” module?
Since we are talking about summation, do we want to provide more robust implementations of sum and cumsum? The Kahan summation (and variants) spring to mind. I can reserve this discussion for the actual cumsum proposal too if need be. Related to #134 about multiple implementations of a concept.
Do we have a name for this module already? Would stdlib_<experimental>_math be too broad?
expm1(x)andlog1p(x)- I suspect that many compilers detectexp(x) - 1.0/log(1.0 + x)and call appropriate library routines, but I'd like to provide these explicitly.
These functions are available in the NSWC Library under the following names:
REXP/DREXP for computing exp(x) - 1REXP1/DREXP1 for computing (exp(x) - 1)/xALNREL/DLNREL for computing log(1 + a) for a > -1RLOG/DRLOG for computing x - 1 - log(x) for x > 0RLOG1/DRLOG1 for computing x - log(1 + x) for x > -1The CBRT/DCBRT function is also available.
Yeah, NSWC has a lot of nice functionality, as long as you don't need complex numbers. But their implementations may still be useful reference material, especially for things like error tolerances for Taylor series approximations and the like.
As for the name, stdlib_experimental_math seems fine. Something more specific like mathutils also seems suitable. If we want to roll these in with special functions, that's fine too.
A good next step would be to write the markdown API for some obviously useful functions and implement the interfaces for them in a module (to be implemented later in submodules). I would take this up myself, but I have a new baby at home.
A good next step would be to write the markdown API for some obviously useful functions and implement the interfaces for them in a module (to be implemented later in submodules). I would take this up myself, but I have a new baby at home.
I've already started with the cube root function, see #214. Congrats! 🎉
Most helpful comment
Yeah, NSWC has a lot of nice functionality, as long as you don't need complex numbers. But their implementations may still be useful reference material, especially for things like error tolerances for Taylor series approximations and the like.
As for the name,
stdlib_experimental_mathseems fine. Something more specific likemathutilsalso seems suitable. If we want to roll these in with special functions, that's fine too.A good next step would be to write the markdown API for some obviously useful functions and implement the interfaces for them in a module (to be implemented later in submodules). I would take this up myself, but I have a new baby at home.