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

specialfunctions: generalize gamma precision #969

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

perazz
Copy link
Member

@perazz perazz commented Mar 27, 2025

Fix #964.

gamma functions always require quad-precision even when not WITH_QP.

Propose to: instead of hard-coded, the KINDs are taken from the lists of available ones.
Because they're sorted with increasing accuracy, generate all accuracies except the last one

  • for single precision: the i+1-th accuracy is used.
  • for all others: the maximum available accuracy is used (because when xdp is available, it is not enough to guarantee accuracy for dp evaluation: qp is always needed if present).

This is a more generalized version than #967.

cc: @jvdp1 @jalvesz @loiseaujc @osada-yum

@perazz
Copy link
Member Author

perazz commented Mar 28, 2025

The CI builds have an issue in complex gamma functions, they have a relative error ~1e-12 with the requested tolerance of ~1e-13. This does not happen on my local setup, it may be related to using extended precision internally rather than quadruple-precision

Copy link
Member

@jvdp1 jvdp1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @perazz . I like this solution. Smart approach IMO.

@osada-yum
Copy link

fpm build fails without --with_qp in my environment

There is something wrong with calling l_gamma using 1.0_dp.

Console

(...) denotes unnecessary lines

 $ python3 config/fypp_deployment.py
 $ /usr/bin/gfortran --version
GNU Fortran (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 $ LANG=C fpm build --compiler="/usr/bin/gfortran" --flag="" --verbose
(...)
[ 12%] stdlib_specialfunctions_gamma.
 + /usr/bin/gfortran -c ././src/temp/stdlib_specialfunctions_gamma.f90  -cpp -Wall -Wextra -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -fimplicit-none -Werror=implicit-interface -ffree-form -DMAXRANK=7 -I././include -J build/gfortran_128FBD428609BDB6 -Ibuild/gfortran_128FBD428609BDB6 -o build/gfortran_128FBD428609BDB6/stdlib/src_temp_stdlib_specialfunctions_gamma.f90.o
././src/temp/stdlib_specialfunctions_gamma.f90:1380:25:

 1380 |                     a = (1 - p - n / 2) * x
      |                         1
Warning: Possible change of value in conversion from INTEGER(8) to REAL(4) at (1) [-Wconversion]
(Warnings...)
././src/temp/stdlib_specialfunctions_gamma.f90:809:18:

  809 |             res = l_gamma(n + 1, 1.0_dp)
      |                  1
Error: There is no specific function for the generic 'l_gamma' at (1)
compilation terminated due to -fmax-errors=1.
[ 12%] stdlib_specialfunctions_gamma.  done.

././src/temp/stdlib_specialfunctions_gamma.f90:1380:25:

 1380 |                     a = (1 - p - n / 2) * x
      |                         1
Warning: Possible change of value in conversion from INTEGER(8) to REAL(4) at (1) [-Wconversion]
././src/temp/stdlib_specialfunctions_gamma.f90:1409:25:

 1409 |             b = x + 1 - p
      |                         1
Warning: Possible change of value in conversion from INTEGER(8) to REAL(4) at (1) [-Wconversion]
(Warnings...)
././src/temp/stdlib_specialfunctions_gamma.f90:809:18:

  809 |             res = l_gamma(n + 1, 1.0_dp)
      |                  1
Error: There is no specific function for the generic 'l_gamma' at (1)
compilation terminated due to -fmax-errors=1.
<ERROR> Compilation failed for object " src_temp_stdlib_specialfunctions_gamma.f90.o "
<ERROR> stopping due to failed compilation
STOP 1

@perazz
Copy link
Member Author

perazz commented Mar 30, 2025

Yes @osada-yum: I did not notice log_gamma would internally use the default real, log_factorial would use real(dp) (that requires qp available).

I have now generalized them too.

@osada-yum
Copy link

Thank you @perazz.
I can now compile stdlib_specialfunctions_gamma.f90 without issues.
However, I'm encountering errors related to complex(dp) in both example_gamma.f90 and example_log_gamma.f90.
Without quad precision, functions gamma and log_gamma do not have kinds about complex(dp) :: z1(e.g. print *, gamma(z1) and print *, log_gamma(z1)).
Please remove those lines about z1.
Once those lines are removed, everything builds successfully. Thank you!

build log in example/specialfunctions_gamma/example_gamma.f90

 + /usr/bin/gfortran -c example/specialfunctions_gamma/example_gamma.f90  -cpp -Wall -Wextra -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -fimplicit-none -Werror=implicit-interface -ffree-form -DMAXRANK=7 -I././include -J build/gfortran_128FBD428609BDB6 -Ibuild/gfortran_128FBD428609BDB6 -o build/gfortran_128FBD428609BDB6/stdlib/example_specialfunctions_gamma_example_gamma.f90.o
example/specialfunctions_gamma/example_gamma.f90:35:10:

   35 |   print *, gamma(z1)
      |          1
Error: Generic function 'gamma' at (1) is not consistent with a specific intrinsic interface
[ 30%]              example_gamma.f90  done.

example/specialfunctions_gamma/example_gamma.f90:35:10:

   35 |   print *, gamma(z1)
      |          1
Error: Generic function 'gamma' at (1) is not consistent with a specific intrinsic interface

build log in example/specialfunctions_gamma/example_log_gamma.f90 after removing those lines

 + /usr/bin/gfortran -c example/specialfunctions_gamma/example_log_gamma.f90  -cpp -Wall -Wextra -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -fimplicit-none -Werror=implicit-interface -ffree-form -DMAXRANK=7 -I././include -J build/gfortran_128FBD428609BDB6 -Ibuild/gfortran_128FBD428609BDB6 -o build/gfortran_128FBD428609BDB6/stdlib/example_specialfunctions_gamma_example_log_gamma.f90.o
example/specialfunctions_gamma/example_log_gamma.f90:32:10:

   32 |   print *, log_gamma(z1)
      |          1
Error: Generic function 'log_gamma' at (1) is not consistent with a specific intrinsic interface
[  1%]          example_log_gamma.f90  done.

example/specialfunctions_gamma/example_log_gamma.f90:32:10:

   32 |   print *, log_gamma(z1)
      |          1
Error: Generic function 'log_gamma' at (1) is not consistent with a specific intrinsic interface

@osada-yum
Copy link

Thank you @perazz.
I can now build stdlib without quadruple precision.

Copy link
Contributor

@jalvesz jalvesz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM @perazz

@perazz
Copy link
Member Author

perazz commented Apr 3, 2025

Thank you @jvdp1 @jalvesz, let us wait a bit longer, and then we can merge imho.

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.

fpm build failure in gamma functions when real128 is unsupported (-1)
4 participants