PROGRAM NAG_test
  IMPLICIT NONE
  INTEGER :: n, ifail, iter, i, iuser(1)
  REAL :: objf, user(1)
  REAL, DIMENSION(:), ALLOCATABLE :: x, objgrd, work
  INTEGER, DIMENSION(:), ALLOCATABLE :: iwork 
  EXTERNAL e04dge, e04dke, fun
  n = 1000
  ALLOCATE(x(n), objgrd(n), work(13*n), iwork(n+1))
  ! Alkuarvaus ratkaisulle
  x(1:n-1:2) = (/ (-1.2d0 - 0.1d0*COS(REAL(i)), i=1,n-1,2) /)
  x(2:n:2) = 1.d0 + 0.1d0*COS(x(1:n-1:2))
  ! Parametrit ratkaisurutiinille
  CALL e04dke('   Maximum step length = 100')
  CALL e04dke('   Optimality tolerance = 1.0d-14')
  CALL e04dke('   Iteration limit = 1000')
  CALL e04dke('   Print level = 1')
  ifail = -1 
  CALL e04dge(n, fun, iter, objf, objgrd, x, iwork, &
      work, iuser, user, ifail)
  WRITE(*,*) 'Minimiarvo: ', objf
END PROGRAM NAG_test

! Minimoitava funktio ja gradienttivektori
SUBROUTINE fun(mode, n, x, objf, objgrd, nstate, iuser, user)
  IMPLICIT NONE
  INTEGER, INTENT(IN) :: mode, n, nstate
  INTEGER, DIMENSION(:), INTENT(IN) :: iuser
  REAL, DIMENSION(n), INTENT(IN) :: x
  REAL, DIMENSION(:), INTENT(IN) :: user
  REAL, INTENT(OUT) :: objf
  REAL, DIMENSION(SIZE(x)), INTENT(OUT) :: objgrd
  INTEGER :: i
  REAL ::  t1, t2
  objf = 0.d0
  DO i = 1, n-1, 2
    t1 = 1.d0 - x(i); t2 = 10.d0*(x(i+1) - x(i)**2)
    ! Kohdefunktion arvo
    objf = objf + t1**2 + t2**2
    ! Gradienttivektori
    objgrd(i+1) = 20.d0*t2
    objgrd(i) = -2.d0*(x(i)*objgrd(i+1) + t1)
  END DO
END SUBROUTINE fun
