1- module testmod_dif1
1+ program example_lmdif1
2+
3+ use minpack_module, only: wp, enorm, lmdif1
4+ use iso_fortran_env, only: nwrite = > output_unit
5+
26implicit none
3- private
4- public fcn, dp
57
6- integer , parameter :: dp= kind (0d0 )
8+ integer , parameter :: n = 3
9+ integer , parameter :: m = 15
10+ integer , parameter :: lwa = m* n+5 * n+ m
11+
12+ integer :: info
13+ real (wp) :: tol, x(n), fvec(m), wa(lwa)
14+ integer :: iwa(n)
15+
16+ ! The following starting values provide a rough fit.
17+ x = [1.0_wp , 1.0_wp , 1.0_wp ]
18+
19+ ! Set tol to the square root of the machine precision. Unless high precision
20+ ! solutions are required, this is the recommended setting.
21+ tol = sqrt (epsilon (1.0_wp ))
22+
23+ call lmdif1(fcn, m, n, x, fvec, tol, info, iwa, wa, lwa)
24+
25+ write (nwrite, ' (5x,a,d15.7//,5x,a,16x,i10//,5x,a//(5x,3d15.7))' ) &
26+ ' FINAL L2 NORM OF THE RESIDUALS' , enorm(m, fvec), &
27+ ' EXIT PARAMETER' , info, &
28+ ' FINAL APPROXIMATE SOLUTION' , x
729
830contains
931
1032subroutine fcn (m , n , x , fvec , iflag )
11- integer , intent (in ) :: m, n
12- integer , intent (inout ) :: iflag
13- real (dp), intent (in ) :: x(n)
14- real (dp), intent (out ) :: fvec(m)
15-
16- integer :: i
17- real (dp) :: tmp1, tmp2, tmp3, y(15 )
18- ! Suppress compiler warning:
19- y(1 ) = iflag
20- y = [1.4D-1 , 1.8D-1 , 2.2D-1 , 2.5D-1 , 2.9D-1 , 3.2D-1 , 3.5D-1 , 3.9D-1 , &
21- 3.7D-1 , 5.8D-1 , 7.3D-1 , 9.6D-1 , 1.34D0 , 2.1D0 , 4.39D0 ]
22-
23- do i = 1 , 15
24- tmp1 = i
25- tmp2 = 16 - i
26- tmp3 = tmp1
27- if (i > 8 ) tmp3 = tmp2
28- fvec(i) = y(i) - (x(1 ) + tmp1/ (x(2 )* tmp2 + x(3 )* tmp3))
29- end do
30- end subroutine
31-
32- end module
3333
34+ integer , intent (in ) :: m
35+ integer , intent (in ) :: n
36+ real (wp), intent (in ) :: x(n)
37+ real (wp), intent (out ) :: fvec(m)
38+ integer , intent (inout ) :: iflag
3439
35- program example_lmdif1
36- use minpack_module, only: enorm, lmdif1
37- use testmod_dif1, only: dp, fcn
38- implicit none
40+ integer :: i
41+ real (wp) :: tmp1, tmp2, tmp3
3942
40- integer :: info, m, n
41- real (dp) :: tol, x(3 ), fvec(15 )
42- integer :: iwa(size (x))
43- real (dp), allocatable :: wa(:)
43+ real (wp),parameter :: y(15 ) = [1.4e-1_wp , 1.8e-1_wp , 2.2e-1_wp , 2.5e-1_wp , 2.9e-1_wp , &
44+ 3.2e-1_wp , 3.5e-1_wp , 3.9e-1_wp , 3.7e-1_wp , 5.8e-1_wp , &
45+ 7.3e-1_wp , 9.6e-1_wp , 1.34e0_wp , 2.1e0_wp , 4.39e0_wp ]
4446
45- ! The following starting values provide a rough fit.
46- x = [1._dp , 1._dp , 1._dp ]
47+ if (iflag > 0 ) then ! just to avoid the compiler warning
48+ do i = 1 , 15
49+ tmp1 = i
50+ tmp2 = 16 - i
51+ tmp3 = tmp1
52+ if (i > 8 ) tmp3 = tmp2
53+ fvec(i) = y(i) - (x(1 ) + tmp1/ (x(2 )* tmp2 + x(3 )* tmp3))
54+ end do
55+ end if
4756
48- ! Set tol to the square root of the machine precision. Unless high precision
49- ! solutions are required, this is the recommended setting.
50- tol = sqrt (epsilon (1._dp ))
51-
52- m = size (fvec)
53- n = size (x)
54- allocate (wa(m* n + 5 * n + m))
55- call lmdif1(fcn, size (fvec), size (x), x, fvec, tol, info, iwa, wa, size (wa))
56- print 1000 , enorm(size (fvec), fvec), info, x
57- 1000 format (5x , ' FINAL L2 NORM OF THE RESIDUALS' , d15.7 // &
58- 5x , ' EXIT PARAMETER' , 16x , i10 // &
59- 5x , ' FINAL APPROXIMATE SOLUTION' // &
60- 5x , 3d15 .7 )
61- end program
57+ end subroutine fcn
58+
59+ end program example_lmdif1
0 commit comments