Code Monkey home page Code Monkey logo

nlopt-f's Introduction

Fortran bindings for the NLopt library

License CI

Fortran bindings for the NLopt library. While the NLopt library supports Fortran by using implicit interface calling conventions, those are not type-safe. This project offers an alternative interface to the NLopt C-API.

Installation

To build this project from the source code in this repository you need to have

  • a Fortran compiler supporting Fortran 2008 (GCC 5 or newer or Intel Fortran)

  • One of the supported build systems

  • nlopt version 2.0.0 or later

Building with meson

Setup a build with

meson setup _build

You can select the Fortran compiler by the FC environment variable. To compile the project run

meson compile -C _build

You can run the projects testsuite with

meson test -C _build --print-errorlogs

To include nlopt-f in your project add the following wrap file to your subprojects directory:

[wrap-git]
directory = nlopt-f
url = https://github.com/grimme-lab/nlopt-f
revision = head

You can retrieve the dependency from the wrap fallback with

nlopt_dep = dependency('nlopt-f', fallback: ['nlopt-f', 'nlopt_dep'])

and add it as dependency to your targets.

Building with CMake

Alternatively, this project can be build with CMake (in this case ninja 1.10 or newer is required):

cmake -B _build -G Ninja

To compile the project with CMake run

cmake --build _build

You can run the project testsuite with

pushd _build && ctest && popd

Finally, install the project using (the install prefix can be customized with -DCMAKE_INSTALL_PREFIX=/path/to/install in the first step)

cmake --install _build

Now you can use it in your CMake project by finding it again

if(NOT "nlopt-f::nlopt-f")
  find_package("nlopt-f" REQUIRED)
endif()
# ...
target_link_libraries("${PROJECT_NAME}-lib" PRIVATE "nlopt-f::nlopt-f")

Building with fpm

Invoke fpm in the project root with

fpm build

To run the testsuite use

fpm test

To use nlopt-f include it as dependency in your package manifest

[dependencies]
nlopt-f.git = "https://github.com/grimme-lab/nlopt-f"

The Fortran bindings target NLopt 2.5.0 by default. You can target a specific NLopt version by adding the preprocessor define NLOPT_VERSION using a compact integer representation (major * 10000 + minor * 100 + patch). To target NLopt 2.6.2 use

fpm <cmd> --profile debug --flag "-DNLOPT_VERSION=20602"

If NLopt is not installed in a standard location use pkg-config to find it

fpm <cmd> --profile debug --flag "$(pkg-config nlopt --cflags --libs-only-L)"

You can check your installed NLopt version using

pkg-config nlopt --modversion

Which will print the version number.

Usage

The Fortran bindings allow an object oriented usage of the NLopt C-API:

module example_funcs
  implicit none

  integer, parameter :: wp = kind(0.0d0)
  type :: constraint_data
    real(wp) :: d(2)
  end type

contains

function myfunc(x, gradient, func_data) result(f)
  real(wp), intent(in) :: x(:)
  real(wp), intent(inout), optional :: gradient(:)
  class(*), intent(in), optional :: func_data
  real(wp) :: f

  if (present(gradient)) then
    gradient(1) = 0.0_wp
    gradient(2) = 0.5_wp / sqrt(x(2))
  endif
  f = sqrt(x(2))
end function myfunc

function myconstraint(x, gradient, func_data) result(f)
  real(wp), intent(in) :: x(:)
  real(wp), intent(inout), optional :: gradient(:)
  class(*), intent(in), optional :: func_data
  real(wp) :: f

  select type(func_data)
  type is(constraint_data)
    associate(a => func_data%d(1), b => func_data%d(2))
      if (present(gradient)) then
        gradient(1) = 3.0_wp * a * (a*x(1) + b)**2
        gradient(2) = -1.0_wp
      endif
      f = (a*x(1) + b)**3 - x(2)
    end associate
  end select
end function myconstraint

end module example_funcs


program example
  use example_funcs
  use nlopt_wrap, only : nlopt_opt, nlopt_func, create, destroy
  use nlopt_enum, only : NLOPT_SUCCESS, algorithm_from_string
  implicit none
  type(nlopt_opt) :: opt
  real(wp) :: lb(2), x(2), minf
  integer :: stat
  type(constraint_data), target :: d1, d2
  real(wp), parameter :: xtol = 1.0e-4_wp

  call create(opt, algorithm_from_string("LD_MMA"), 2)

  call opt%get_lower_bounds(lb)

  lb(2) = 0.0_wp
  call opt%set_lower_bounds(lb)

  d1%d = [+2.0_wp, +0.0_wp]
  d2%d = [-1.0_wp, +1.0_wp]
  associate(&
      & f => nlopt_func(myfunc), &
      & fc1 => nlopt_func(myconstraint, d1), &
      & fc2 => nlopt_func(myconstraint, d2))
    call opt%set_min_objective(f)

    call opt%add_inequality_constraint(fc1, 1.0e-8_wp)
    call opt%add_inequality_constraint(fc2, 1.0e-8_wp)

    call opt%set_xtol_rel(xtol)

    x = [1.234_wp, 5.678_wp]
    call opt%optimize(x, minf, stat)
  end associate

  if (stat < NLOPT_SUCCESS) then
    write(*, '(a)') "NLopt failed!"
    stop 1
  endif

  write(*, '(a, *(1x, g0))') "Found minimum at", x
  write(*, '(a, *(1x, g0))') "Minimum value is", minf

  call destroy(opt)
end program example

License

This project is free software: you can redistribute it and/or modify it under the terms of the Apache License, Version 2.0 or MIT license at your opinion.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an as is basis, without warranties or conditions of any kind, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

nlopt-f's People

Contributors

awvwgk avatar ivan-pi avatar nicholaswogan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nlopt-f's Issues

Infinite loop during install

I'm trying to compile and use nlopt-f on a Windows system with msys2 and cmake. The build works fine but if I try to install with cmake --build build -t install I get an infinite loop. The log output is:

[0/1] Install the project...-- Install configuration: "Release"
-- Installing: C:/Users/<user>/nlopt-f/install/lib/cmake/nlopt-f/nlopt-f-config.cmake
-- Installing: C:/Users/<user>/nlopt-f/install/lib/cmake/nlopt-f/nlopt-f-config-version.cmake
-- Installing: C:/Users/<user>/nlopt-f/install/lib/pkgconfig/nlopt-f.pc
-- Installing: C:/Users/<user>/nlopt-f/install/lib/libnlopt-f.a
-- Installing: C:/Users/<user>/nlopt-f/install/lib/cmake/nlopt-f/nlopt-f-targets.cmake
-- Installing: C:/Users/<user>/nlopt-f/install/lib/cmake/nlopt-f/nlopt-f-targets-release.cmake
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0   
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f
-- Installing: C:/Users/<user>/nlopt-f/install/include/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0/nlopt-f/GNU-12.2.0
...

Testing for older GCC versions?

It seems that we can only test for GCC 7 and newer with our available CI runners. However, this project doesn't use any features not available in GCC 5 and should therefore in principle be compatible, yet we have no way for testing this.

While GCC 8 and older are already officially dropped from support upstream, there are probably still users for those compilers. Since it is going to become more difficult to test those versions, providing support on best effort basis is likely the only thing we can offer. If support for older GCC versions breaks, it will be dropped.

Support force stop

We have bindings for the force stop procedure, however there is no way to use them easily from the callback as we need access to the handle to make use of it.

Having the function wrapper store the handle might be an option, however this makes it more difficult to reuse a function in different optimizers.

Use without build systems?

Hello!
Say I'm using a simple Makefile or other very simple "manual" command to compile my code. What are the -I and -L I need?
Using

-I/usr/local/include/nlopt-f/GNU-9.3.0 -L/usr/local/lib -lnlopt-f -lnlopt -lm

compiles fine, but then when I try to run the resulting executable I get

./test: symbol lookup error: ./test: undefined symbol: nlopt_algorithm_from_string

I can run the executable file if I set LD_LIBRARY_PATH before execution, to include /usr/local/lib.

I installed with cmake/ninja. Is it possible to configure it easily to install the .a and .mod-s and so on in locations that are by default in the LD_LIBRARY_PATH and include path, or is it a problem with my system (Ubuntu LTS)?

Thank you!

Error for private component of 'nlopt_func'

Dear all:

Not sure whether this is a good place to post this issue, yet I cannot any helpful documentation about how to nlopt-f binding.

I am now learning how to use this fortran binding to use nlopt to solve my model. My current progress is here, and now when I compile this project using fpm run, I got the following error, and somehow I just don't know how to solve it:

:!fpm run --flag="-O3"
fpm: Entering directory '/home/huijunchen/mnt/home/huijunchen/Documents/Google_Drive/Ohio_related/PhD_Fourth_Year/research/nlopt_test/neoclassical_
nlopt_ver2'
 [   0%]   neoclassical_nlopt_ver2.f90
 [  25%]   neoclassical_nlopt_ver2.f90  done.

./src/neoclassical_nlopt_ver2.f90:133:36:

  133 |         call opt%set_max_objective(nlopt_func(kupObj, evvec))
      |                                    1
Error: Component ‘f’ at (1) is a PRIVATE component of ‘nlopt_func’
<ERROR> Compilation failed for object " src_neoclassical_nlopt_ver2.f90.o "
<ERROR>stopping due to failed compilation
STOP 1

Thank you so much in advance for your help!

HJ

'enum' test case failed

Hi, I tried to install nlopt-f and ran the test and got the 'enum' test failed with the output like this:

ctest --rerun-failed --output-on-failure
Test project /Users/vanc2/projects/nlopt-f/_build
    Start 1: enum
1/1 Test #1: enum .............................***Failed    0.01 sec
# Testing: enum
  Starting result-string ... (1/4)
       ... result-string [PASSED]
  Starting algorithm-name ... (2/4)
       ... algorithm-name [FAILED]
  Message: Condition not fullfilled
  Starting algorithm-invalid ... (3/4)
       ... algorithm-invalid [PASSED]
  Starting algorithm-string ... (4/4)
       ... algorithm-string [PASSED]
1 test(s) failed!
ERROR STOP 1

Error termination. Backtrace:
#0  0x103a3341d
#1  0x103a340a5
#2  0x103a352ce
#3  0x1034ad779
#4  0x1034b72ee


0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.02 sec

The following tests FAILED:
	  1 - enum (Failed)
Errors while running CTest

Please help to fix it or lead me to fix it. Thanks!

Static build

I'm trying to use nlopt-f in a statically compiled executable. But the build process of nlopt-f fails if BUILD_SHARED_LIBS=OFF is used.

# Building NLopt
cd nlopt
cmake -B build -S . -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=install
cmake --build build
cmake --build build -t install

# Building nlopt-f
cd ../nlopt-f
cmake -B build -S . -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=install -DNLopt_DIR=../nlopt/install/lib/cmake/nlopt
cmake --build build

Linker fails with undefined reference error. An excerpt of the log:

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0xa3): undefined reference to `std::runtime_error::runtime_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0xb2): undefined reference to `operator delete(void*)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0xb9): undefined reference to `std::runtime_error::~runtime_error()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0xc8): undefined reference to `__cxa_throw'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0xd3): undefined reference to `__cxa_free_exception'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0xed): undefined reference to `operator delete(void*)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0x42b): undefined reference to `operator new(unsigned long long)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0x45c): undefined reference to `operator delete(void*)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.text+0xcf0): undefined reference to `std::__throw_length_error(char const*)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/<user>/nlopt/install/lib/libnlopt.a(local_optimizer.cc.obj):local_optimize:(.xdata+0x10): undefined reference to `__gxx_personality_seh0'
collect2.exe: error: ld returned 1 exit status

If I build also the shared libraries of NLopt the build process of nlopt-f works but my executable has a dependency to the shared library of NLopt.

add topics

Since optimization repos are often about compiler optimization, I suggest adding the topics numerical-optimization, nonlinear-optimization, mathematical-programming.

Alternative to associating objective functions

Currently we implement objective functions by

  1. creating callback wrappers with bind(c) and pass those as procedure pointers to NLopt
  2. safe the actual user-defined objective function as data pointer (void*)
  3. resolve the user-defined objective function from our callback wrapper
  4. invoke the actual objective function

The drawback of this approach is that we only have a pointer to the objective function and the function object must at least exist until we call the optimize method. Therefore, using the following (intuitive) approach will fail:

call opt%set_min_objective(nlopt_func(myfunc))

call opt%add_inequality_constraint(nlopt_func(myconstraint, d1), 1.0e-8_wp)
call opt%add_inequality_constraint(nlopt_func(myconstraint, d2), 1.0e-8_wp)

call opt%set_xtol_rel(xtol)

x = [1.234_wp, 5.678_wp]
call opt%optimize(x, minf, stat)

Since the function objects contain only a procedure pointer and a class polymorphic pointer, which don't own any data, we could in principle copy those objects into our nlopt_opt instance on the Fortran side and ensure they have the same lifetime as the instance itself.

This would be done in one of the hooks to register an objective function like

nlopt-f/src/nlopt_wrap.f90

Lines 281 to 290 in 696b0e2

subroutine set_min_objective(self, f, stat)
class(nlopt_opt), intent(inout) :: self
type(nlopt_func), intent(in), target :: f
integer(ik), intent(out), optional :: stat
integer(nlopt_result) :: istat
istat = nlopt_set_min_objective(self%handle, c_funloc(wrap_func), c_loc(f))
call handle_result(stat, istat)
end subroutine set_min_objective

However, any mechanism to own the function object in the nlopt_opt instance must ensure that the address of the function object is not changed by any operation on the wrapper, e.g. adding another objective function and resizing an array of function objects.

Help needed?

Hello Sebastian,

I have the feeling like you went through the trouble of doing a full interface rewrite?

I had attempted a Fortran interface a few years ago, but never completed it: stevengj/nlopt#233
An issue I ran into at the time was memory leaks, when calling the remove inequality constraints.
Recently I also started to make an fpm compatible version in a private repo, after realizing this is in fact an easier distribution method than contributing to the upstream.

I understand you support both function and derived-type call back interfaces? 🚀 Just like I did you are using an adaptor pattern to conform to the original NLopt interface.

Are there any remaining areas where you could use some help? I'm very familiar with NLopt and even used it in a paper I submitted. I'm really happy I get to use it as a fpm package now!

Error in configuration file

@awvwgk,

this error appears with cmake:

``
CMake Error at CMakeLists.txt:33 (math):
math cannot parse the expression: " * 10000

+ * 100
+": syntax error, unexpected exp_TIMES (2).

--
cmake version 3.16.3
ninja version 1.10.0
Fortran compiler 9.3.0

Callback function design

The callbacks for this bindings are implemented in an ad hoc fashion, with the primary aim to closely match the NLopt API in a Fortran-friendly way. However, this might not be the best/only way to define a callback. A better target for designing the callback for the objective function should be to provide an uniform experience compared to other optimization libraries.

The callback is for this project is defined in src/nlopt_callback.f90. Note that this callback design creates an issue with object lifetimes (see #13).

Related:

Should nlopt_opt be finalized?

I'm interested in the rationale behind preserving explicit destruction of the optimization object instance instead of wrapping this within a finalizer.

I can see a few reasons why'd you keep this as the user's responsibility, primarily to avoid dealing with the odd behavior prescribed by the Fortran standard.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.