From adf4ddfe1f5627969764c1e64e750bfeeccce611 Mon Sep 17 00:00:00 2001 From: Thomas Guymer Date: Sat, 10 Aug 2024 11:17:00 +0100 Subject: [PATCH] add ability to use my FORTRAN implementation of the hypergeometric function --- mod_f2py.F90 | 1 + mod_f2py/sub_hypergeometric.f90 | 21 +++++++++++++++++++++ tests/func_t_CDF.py | 7 +++++-- tests/func_t_PDF.py | 2 +- 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 mod_f2py/sub_hypergeometric.f90 diff --git a/mod_f2py.F90 b/mod_f2py.F90 index 07737d8..f7fc12a 100644 --- a/mod_f2py.F90 +++ b/mod_f2py.F90 @@ -7,6 +7,7 @@ MODULE mod_f2py CONTAINS ! Include functions and subroutines ... + INCLUDE "mod_f2py/sub_hypergeometric.f90" INCLUDE "mod_f2py/sub_t_CDF.f90" INCLUDE "mod_f2py/sub_t_PDF.f90" END MODULE mod_f2py diff --git a/mod_f2py/sub_hypergeometric.f90 b/mod_f2py/sub_hypergeometric.f90 new file mode 100644 index 0000000..28925cf --- /dev/null +++ b/mod_f2py/sub_hypergeometric.f90 @@ -0,0 +1,21 @@ +PURE SUBROUTINE sub_hypergeometric(a, b, c, z, ans) + !f2py threadsafe + + ! Import standard modules ... + USE ISO_C_BINDING + + ! Import my modules ... + USE mod_safe, ONLY: func_hypergeometric + + IMPLICIT NONE + + ! Declare inputs/outputs ... + REAL(kind = C_DOUBLE), INTENT(in) :: a + REAL(kind = C_DOUBLE), INTENT(in) :: b + REAL(kind = C_DOUBLE), INTENT(in) :: c + REAL(kind = C_DOUBLE), INTENT(in) :: z + REAL(kind = C_DOUBLE), INTENT(out) :: ans + + ! Calculate answer ... + ans = func_hypergeometric(a, b, c, z) +END SUBROUTINE sub_hypergeometric diff --git a/tests/func_t_CDF.py b/tests/func_t_CDF.py index 482ac84..3dbaa7f 100644 --- a/tests/func_t_CDF.py +++ b/tests/func_t_CDF.py @@ -15,7 +15,7 @@ from mod_f2py import mod_f2py # Define function ... -def t_CDF(x, dof): +def t_CDF(x, dof, /, *, fortran = True): """This function calculates the CDF of Student's t-distribution in the same way as the FORTRAN function in this repository. """ @@ -52,7 +52,10 @@ def t_CDF(x, dof): z = - (x ** 2 / dof) # Calculate CDF ... - ans = a + x * math.gamma(b) * scipy.special.hyp2f1(a, b, c, z) / (math.sqrt(dof * math.pi) * math.gamma(0.5 * dof)) + if fortran: + ans = a + x * math.gamma(b) * mod_f2py.sub_hypergeometric(a, b, c, z) / (math.sqrt(dof * math.pi) * math.gamma(0.5 * dof)) + else: + ans = a + x * math.gamma(b) * scipy.special.hyp2f1(a, b, c, z) / (math.sqrt(dof * math.pi) * math.gamma(0.5 * dof)) # Return answer ... return ans diff --git a/tests/func_t_PDF.py b/tests/func_t_PDF.py index c0ff23e..860e59e 100644 --- a/tests/func_t_PDF.py +++ b/tests/func_t_PDF.py @@ -15,7 +15,7 @@ from mod_f2py import mod_f2py # Define function ... -def t_PDF(x, dof): +def t_PDF(x, dof, /): """This function calculates the PDF of Student's t-distribution in the same way as the FORTRAN function in this repository. """