|
| 1 | +module testmod |
| 2 | +implicit none |
| 3 | +private |
| 4 | +public fcn, dp |
| 5 | + |
| 6 | +integer, parameter :: dp=kind(0d0) |
| 7 | + |
| 8 | +contains |
| 9 | + |
| 10 | +subroutine fcn(m, n, x, fvec, fjac, ldfjac, iflag) |
| 11 | +integer, intent(in) :: m, n, ldfjac, iflag |
| 12 | +real(dp), intent(in) :: x(n) |
| 13 | +real(dp), intent(out) :: fvec(m), fjac(ldfjac, n) |
| 14 | + |
| 15 | +integer :: i |
| 16 | +real(dp) :: tmp1, tmp2, tmp3, tmp4, y(15) |
| 17 | +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, & |
| 18 | + 3.7D-1, 5.8D-1, 7.3D-1, 9.6D-1, 1.34D0, 2.1D0, 4.39D0] |
| 19 | + |
| 20 | +if (iflag == 1) then |
| 21 | + do i = 1, 15 |
| 22 | + tmp1 = i |
| 23 | + tmp2 = 16 - i |
| 24 | + tmp3 = tmp1 |
| 25 | + if (i .gt. 8) tmp3 = tmp2 |
| 26 | + fvec(i) = y(i) - (x(1) + tmp1/(x(2)*tmp2 + x(3)*tmp3)) |
| 27 | + end do |
| 28 | +else |
| 29 | + do i = 1, 15 |
| 30 | + tmp1 = i |
| 31 | + tmp2 = 16 - i |
| 32 | + tmp3 = tmp1 |
| 33 | + if (i .gt. 8) tmp3 = tmp2 |
| 34 | + tmp4 = (x(2)*tmp2 + x(3)*tmp3)**2 |
| 35 | + fjac(i,1) = -1.D0 |
| 36 | + fjac(i,2) = tmp1*tmp2/tmp4 |
| 37 | + fjac(i,3) = tmp1*tmp3/tmp4 |
| 38 | + end do |
| 39 | +end if |
| 40 | +end subroutine |
| 41 | + |
| 42 | +end module |
| 43 | + |
| 44 | + |
| 45 | +program example_lmder1 |
| 46 | +use minpack, only: enorm, dpmpar, lmder1 |
| 47 | +use testmod, only: dp, fcn |
| 48 | +implicit none |
| 49 | + |
| 50 | +integer :: info |
| 51 | +real(dp) :: tol, x(3), fvec(15), fjac(size(fvec), size(x)) |
| 52 | +integer :: ipvt(size(x)) |
| 53 | +real(dp), allocatable :: wa(:) |
| 54 | + |
| 55 | +! The following starting values provide a rough fit. |
| 56 | +x = [1._dp, 1._dp, 1._dp] |
| 57 | + |
| 58 | +! Set tol to the square root of the machine precision. Unless high precision |
| 59 | +! solutions are required, this is the recommended setting. |
| 60 | +tol = sqrt(dpmpar(1)) |
| 61 | + |
| 62 | +allocate(wa(5*size(x) + size(fvec))) |
| 63 | +call lmder1(fcn, size(fvec), size(x), x, fvec, fjac, size(fjac, 1), tol, & |
| 64 | + info, ipvt, wa, size(wa)) |
| 65 | +print 1000, enorm(size(fvec), fvec), info, x |
| 66 | +1000 format(5x, 'FINAL L2 NORM OF THE RESIDUALS', d15.7 // & |
| 67 | + 5x, 'EXIT PARAMETER', 16x, i10 // & |
| 68 | + 5x, 'FINAL APPROXIMATE SOLUTION' // & |
| 69 | + 5x, 3d15.7) |
| 70 | +end program |
0 commit comments