chiark / gitweb /
Add fortran test
authorJulien Schueller <schueller@phimeca.com>
Wed, 14 Nov 2018 09:26:29 +0000 (10:26 +0100)
committerJulien Schueller <schueller@phimeca.com>
Wed, 14 Nov 2018 09:49:38 +0000 (10:49 +0100)
.travis.yml
CMakeLists.txt
test/CMakeLists.txt
test/t_fortran.f90 [new file with mode: 0644]

index 8f334d87f65701d2bdce8723be9ae608f86a8602..e2c712d9eae661327a116269b47ca26fc3e9fc4a 100644 (file)
@@ -19,11 +19,13 @@ matrix:
           - g++-mingw-w64-x86-64
           - gcc-mingw-w64-x86-64
           - binutils-mingw-w64-x86-64
+          - gfortran
+
       script:
         - pip install mkdocs python-markdown-math --user
         - PATH=$PATH:~/.local/bin mkdocs build
         - mkdir build && pushd build
-        - cmake -DCMAKE_INSTALL_PREFIX=~/.local -DNLOPT_MATLAB=OFF ..
+        - cmake -DCMAKE_INSTALL_PREFIX=~/.local -DNLOPT_MATLAB=OFF -DNLOPT_FORTRAN=ON ..
         - make install -j2 && ctest -j2 --output-on-failure
         - rm -rf * ~/.local
         - cmake -DCMAKE_INSTALL_PREFIX=~/.local -DNLOPT_PYTHON=OFF -DNLOPT_OCTAVE=OFF -DNLOPT_GUILE=OFF -DNLOPT_MATLAB=OFF -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/toolchain-i686-w64-mingw32.cmake ..
@@ -38,5 +40,5 @@ matrix:
         - brew install swig octave guile || echo "nope"
       script:
         - mkdir build && pushd build
-        - cmake -DCMAKE_INSTALL_PREFIX=~/.local -DPYTHON_EXECUTABLE=/usr/bin/python ..
+        - cmake -DCMAKE_INSTALL_PREFIX=~/.local -DPYTHON_EXECUTABLE=/usr/bin/python -DNLOPT_FORTRAN=ON ..
         - make install && ctest --output-on-failure
index 2cf3289aa6ef8c35a3d298db810113928b835894..22852957e804f0570b791db91a8920517546fda5 100644 (file)
@@ -38,6 +38,7 @@ set(SO_PATCH 0)
 list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
 
 option (NLOPT_CXX "enable cxx routines" ON)
+option (NLOPT_FORTRAN "enable fotran tests" OFF)
 option (BUILD_SHARED_LIBS "Build NLopt as a shared library" ON)
 option (NLOPT_PYTHON "build python bindings" ON)
 option (NLOPT_OCTAVE "build octave bindings" ON)
@@ -51,6 +52,10 @@ else ()
   option (NLOPT_TESTS "build unit tests" OFF)
 endif ()
 
+if (NLOPT_FORTRAN)
+  enable_language (Fortran)
+endif ()
+
 include (GNUInstallDirs)
 
 # Offer the user the choice of overriding the installation directories
index 4154eb90000d7385ec71cae6960bbcdc3fc77a96..8f016ff658706b0d99c2aec091c606b569b550b0 100644 (file)
@@ -59,3 +59,9 @@ if (GUILE_FOUND AND ((SWIG_FOUND AND SWIG_VERSION VERSION_GREATER 2.0.9) OR (EXI
   add_test (NAME test_guile COMMAND ${GUILE_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/t_guile.scm)
   set_tests_properties (test_guile PROPERTIES ENVIRONMENT "${GUILECHECK_ENVIRONMENT}")
 endif ()
+
+if (NLOPT_FORTRAN)
+  add_executable (t_fortran t_fortran.f90)
+  target_link_libraries (t_fortran ${nlopt_lib})
+  add_test (NAME test_fortran COMMAND t_fortran)
+endif ()
diff --git a/test/t_fortran.f90 b/test/t_fortran.f90
new file mode 100644 (file)
index 0000000..48cb109
--- /dev/null
@@ -0,0 +1,61 @@
+program main
+  external myfunc, myconstraint
+  double precision lb(2)
+  integer*8 opt
+  double precision d1(2), d2(2)
+  double precision x(2), minf
+  integer ires
+  include 'nlopt.f'
+
+  opt=0
+  call nlo_create(opt, NLOPT_LD_MMA, 2)
+  call nlo_get_lower_bounds(ires, opt, lb)
+  lb(2) = 0.0
+  call nlo_set_lower_bounds(ires, opt, lb)
+  call nlo_set_min_objective(ires, opt, myfunc, 0)
+
+  d1(1) = 2.
+  d1(2) = 0.
+  call nlo_add_inequality_constraint(ires, opt, myconstraint, d1, 1.D-8)
+  d2(1) = -1.
+  d2(2) = 1.
+  call nlo_add_inequality_constraint(ires, opt, myconstraint, d2, 1.D-8)
+
+  call nlo_set_xtol_rel(ires, opt, 1.D-4)
+
+  x(1) = 1.234
+  x(2) = 5.678
+  call nlo_optimize(ires, opt, x, minf)
+  if (ires.lt.0) then
+    write(*,*) 'nlopt failed!'
+    stop 1
+  else
+    write(*,*) 'found min at ', x(1), x(2)
+    write(*,*) 'min val = ', minf
+  endif
+
+  call nlo_destroy(opt)
+
+  end 
+
+  subroutine myfunc(val, n, x, grad, need_gradient, f_data)
+  double precision val, x(n), grad(n)
+  integer n, need_gradient
+  if (need_gradient.ne.0) then
+     grad(1) = 0.0
+     grad(2) = 0.5 / dsqrt(x(2))
+  endif
+  val = dsqrt(x(2))
+  end 
+
+  subroutine myconstraint(val, n, x, grad, need_gradient, d)
+  integer need_gradient
+  double precision val, x(n), grad(n), d(2), a, b
+  a = d(1)
+  b = d(2)
+  if (need_gradient.ne.0) then
+    grad(1) = 3. * a * (a*x(1) + b)**2
+    grad(2) = -1.0
+  endif
+  val = (a*x(1) + b)**3 - x(2)
+  end