    MODULE nlin_lsq_ex04_mod

      ! .. Implicit None Statement ..
      IMPLICIT NONE
      ! .. Default Accessibility ..
      PUBLIC
      ! .. Intrinsic Functions ..
      INTRINSIC KIND
      ! .. Parameters ..
      INTEGER, PARAMETER :: wp = KIND(1.0D0)
      ! .. Local Arrays ..
      REAL (wp), ALLOCATABLE :: t(:,:), y(:)

    CONTAINS

      SUBROUTINE lsq_fun(x,finish,f_vec,f_jac)

        ! .. Implicit None Statement ..
        IMPLICIT NONE
        ! .. Intrinsic Functions ..
        INTRINSIC SIZE
        ! .. Scalar Arguments ..
        LOGICAL, INTENT (INOUT) :: finish
        ! .. Array Arguments ..
        REAL (wp), OPTIONAL, INTENT (OUT) :: f_jac(:,:)
        REAL (wp), INTENT (OUT) :: f_vec(:)
        REAL (wp), INTENT (IN) :: x(:)
        ! .. Local Scalars ..
        INTEGER :: i
        REAL (wp) :: denom
        ! .. Executable Statements ..
        DO i = 1, SIZE(f_vec)
          denom = x(2)*t(i,2) + x(3)*t(i,3)
          f_vec(i) = x(1) + t(i,1)/denom - y(i)
        END DO

      END SUBROUTINE lsq_fun

    END MODULE nlin_lsq_ex04_mod

    PROGRAM nag_nlin_lsq_ex04

      ! Example Program Text for nag_nlin_lsq
      ! NAG fl90, Release 4. NAG Copyright 2000.

      ! .. Use Statements ..
      USE nag_examples_io, ONLY : nag_std_in, nag_std_out
      USE nag_nlin_lsq, ONLY : nag_nlin_lsq_sol, nag_nlin_lsq_cntrl_init, &
       nag_nlin_lsq_cov, nag_nlin_lsq_cntrl_wp => nag_nlin_lsq_cntrl_dp
      USE nlin_lsq_ex04_mod, ONLY : lsq_fun, t, y, wp
      ! .. Implicit None Statement ..
      IMPLICIT NONE
      ! .. Local Scalars ..
      INTEGER :: i, m, n, r
      REAL (wp) :: f_sum_sq
      TYPE (nag_nlin_lsq_cntrl_wp) :: control
      ! .. Local Arrays ..
      REAL (wp), ALLOCATABLE :: cj(:), f_vec(:), s(:), v(:,:), x(:)
      ! .. Executable Statements ..
      WRITE (nag_std_out,*) 'Example Program Results for nag_nlin_lsq_ex04'

      READ (nag_std_in,*)          ! Skip heading in data file

      ! Read number of observations (m), variables (n) and controls (r)
      READ (nag_std_in,*) m, n, r

      ALLOCATE (f_vec(m),x(n),t(m,r),y(m),s(n),v(n,n), &
       cj(n))                      ! Allocate storage

      ! Read in data for y and corresponding controls t(1,2,...,r)
      READ (nag_std_in,*) (y(i),t(i,:),i=1,m)

      ! Read the starting point x
      READ (nag_std_in,*) x

      ! Initialize the structure
      CALL nag_nlin_lsq_cntrl_init(control)

      ! Change the value of print_level to 0 (default = 10)
      control%print_level = 0
      control%list = .FALSE.

      ! Solve the problem
      CALL nag_nlin_lsq_sol(lsq_fun,x,f_sum_sq,f_vec,deriv=.FALSE.,s=s,v=v, &
       control=control)

      ! Compute estimates of the variances of the sample
      ! regression coefficients at the final point (x).
      CALL nag_nlin_lsq_cov(f_vec,s,v,cj=cj)

      WRITE (nag_std_out,*)
      WRITE (nag_std_out,fmt='(1x,a,i2,a)') &
       'estimates of the variances of the sample regression coefficients'
      WRITE (nag_std_out,fmt='(1x,f12.4)') cj

      DEALLOCATE (cj,f_vec,s,t,v,x,y) ! Deallocate storage

    END PROGRAM nag_nlin_lsq_ex04
