From ca81abe2fb6b331319b4caa0f08f36d34835ba00 Mon Sep 17 00:00:00 2001 From: Julien Schueller Date: Wed, 14 Nov 2018 10:26:29 +0100 Subject: [PATCH] Add fortran test --- .travis.yml | 6 +++-- CMakeLists.txt | 5 ++++ test/CMakeLists.txt | 6 +++++ test/t_fortran.f90 | 61 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 test/t_fortran.f90 diff --git a/.travis.yml b/.travis.yml index 8f334d8..e2c712d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cf3289..2285295 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4154eb9..8f016ff 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 index 0000000..48cb109 --- /dev/null +++ b/test/t_fortran.f90 @@ -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 -- 2.30.2