Skip to content

Commit f07655f

Browse files
committed
refactor primes example
1 parent 11d68d0 commit f07655f

File tree

1 file changed

+53
-53
lines changed

1 file changed

+53
-53
lines changed

examples/example_primes.f90

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
1-
module types
2-
implicit none
3-
private
4-
public dp
5-
6-
integer, parameter :: dp=kind(0d0)
7-
8-
end module
9-
101
module find_fit_module
112

12-
! This module contains a general function find_fit() for a nonlinear least
13-
! squares fitting. The function can fit any nonlinear expression to any data.
3+
!! This module contains a general function find_fit() for a nonlinear least
4+
!! squares fitting. The function can fit any nonlinear expression to any data.
5+
6+
use minpack_module, only: wp, lmdif1
147

15-
use minpack_module, only: lmdif1
16-
use types, only: dp
178
implicit none
9+
1810
private
19-
public find_fit
11+
12+
abstract interface
13+
function expr_f(x, pars) result(y)
14+
import :: wp
15+
implicit none
16+
real(wp), intent(in) :: x(:)
17+
real(wp), intent(in) :: pars(:)
18+
real(wp) :: y(size(x))
19+
end function expr_f
20+
end interface
21+
22+
public :: find_fit
2023

2124
contains
2225

@@ -26,71 +29,68 @@ subroutine find_fit(data_x, data_y, expr, pars)
2629
! parameters 'pars' and it must return the evaluated expression on the
2730
! array 'x'. The arrays 'data_x' and 'data_y' must have the same
2831
! length.
29-
real(dp), intent(in) :: data_x(:), data_y(:)
30-
interface
31-
function expr(x, pars) result(y)
32-
use types, only: dp
33-
implicit none
34-
real(dp), intent(in) :: x(:), pars(:)
35-
real(dp) :: y(size(x))
36-
end function
37-
end interface
38-
real(dp), intent(inout) :: pars(:)
32+
real(wp), intent(in) :: data_x(:)
33+
real(wp), intent(in) :: data_y(:)
34+
procedure(expr_f) :: expr
35+
real(wp), intent(inout) :: pars(:)
3936

40-
real(dp) :: tol, fvec(size(data_x))
37+
real(wp) :: tol, fvec(size(data_x))
4138
integer :: iwa(size(pars)), info, m, n
42-
real(dp), allocatable :: wa(:)
39+
real(wp), allocatable :: wa(:)
4340

44-
tol = sqrt(epsilon(1._dp))
41+
tol = sqrt(epsilon(1.0_wp))
4542
m = size(fvec)
4643
n = size(pars)
4744
allocate(wa(m*n + 5*n + m))
4845
call lmdif1(fcn, m, n, pars, fvec, tol, info, iwa, wa, size(wa))
49-
if (info /= 1) stop "failed to converge"
46+
if (info /= 1) error stop "failed to converge"
5047

5148
contains
5249

53-
subroutine fcn(m, n, x, fvec, iflag)
54-
integer, intent(in) :: m, n
55-
integer, intent(inout) :: iflag
56-
real(dp), intent(in) :: x(n)
57-
real(dp), intent(out) :: fvec(m)
58-
! Suppress compiler warning:
59-
fvec(1) = iflag
60-
fvec = data_y - expr(data_x, x)
61-
end subroutine
50+
subroutine fcn(m, n, x, fvec, iflag)
51+
integer, intent(in) :: m
52+
integer, intent(in) :: n
53+
integer, intent(inout) :: iflag
54+
real(wp), intent(in) :: x(n)
55+
real(wp), intent(out) :: fvec(m)
56+
fvec(1) = iflag ! Suppress compiler warning:
57+
fvec = data_y - expr(data_x, x)
58+
end subroutine fcn
6259

63-
end subroutine
64-
65-
end module
60+
end subroutine find_fit
6661

62+
end module find_fit_module
6763

6864
program example_primes
6965

70-
! Find a nonlinear fit of the form a*x*log(b + c*x) to a list of primes.
66+
!! Find a nonlinear fit of the form `a*x*log(b + c*x)` to a list of primes.
7167

7268
use find_fit_module, only: find_fit
73-
use types, only: dp
69+
use minpack_module, only: wp
70+
use iso_fortran_env, only: nwrite => output_unit
71+
7472
implicit none
7573

76-
real(dp) :: pars(3)
77-
real(dp), parameter :: y(*) = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, &
78-
37, 41, 43, 47, 53, 59, 61, 67, 71]
74+
real(wp) :: pars(3)
75+
real(wp), parameter :: y(*) = real([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, &
76+
37, 41, 43, 47, 53, 59, 61, 67, 71], wp)
7977
integer :: i
80-
pars = [1._dp, 1._dp, 1._dp]
81-
call find_fit([(real(i, dp), i=1,size(y))], y, expression, pars)
82-
print *, pars
78+
pars = [1.0_wp, 1.0_wp, 1.0_wp]
79+
call find_fit([(real(i, wp), i=1,size(y))], y, expression, pars)
80+
81+
write(nwrite, '(1p,5x,a/(5x,3e15.7))') 'pars: ',pars
8382

8483
contains
8584

8685
function expression(x, pars) result(y)
87-
real(dp), intent(in) :: x(:), pars(:)
88-
real(dp) :: y(size(x))
89-
real(dp) :: a, b, c
86+
real(wp), intent(in) :: x(:)
87+
real(wp), intent(in) :: pars(:)
88+
real(wp) :: y(size(x))
89+
real(wp) :: a, b, c
9090
a = pars(1)
9191
b = pars(2)
9292
c = pars(3)
9393
y = a*x*log(b + c*x)
94-
end function
94+
end function expression
9595

96-
end program
96+
end program example_primes

0 commit comments

Comments
 (0)