On May 28, 2010, at 1:35 PM, Dmitri Tchikine wrote:
On 29/05/2010 3:05 AM, Steven G. Johnson wrote:
That's why the STOGO library is not compiled into NLopt by default.
Sorry, Steven, I missed that point. No, it is not included by
default; point taken.
For example, compiling a Fortran program that links to a C++ using
library is a pain, because the user has to either link using the
Fortran compiler and figure out which C++ libraries need to be
linked, or link with the C++ compiler and figure out which Fortran
libraries need to be linked.
Interesting.
Steven, STL does not - as I remember - require any C++ libraries. It
is purely inline. The only difference may be memory allocation
functions you call (or STL calls) - like "new" operator instead of
malloc.
Just STOGO by itself pulls in a whole bunch of C++ library
dependencies, as I recall, and already caused headaches when I tried
to link with Fortran. This can occur via things like memory allocation
as you point out, although I didn't try to track it down.
Anyway, if you take your C library (drop STOGO), and compile it with
C++ compiler, will users see the difference?
If not, you can safely add some auto_ptr<T> of your own (for single
threads it is almost trivial to write), and use it in your code.
Nothing will change for the user, but the code will become "leak-
safe".
It might depend on the compiler whether this implicitly pulls in
library dependencies (it is not unusual for compilers to generate
calls to private library functions for various things, even if the
user calls no library functions implicitly.... even gcc does this
sometimes, with libgcc, e.g. for some 64-bit arithmetic functions on
32-bit machines). It would be interesting to try it with g++ and see.
I think we can close this discussion - I see no need in pressing my
point, as I see that there are more serious concerns.
Still, what got me worried was the mention of some
nlopt_destroy(opt);
function. I got the impression that you may pass more
responsibilities to the client code - and it is never a good idea,
in my experience.
I like the current clean interface: stateless calls with no side-
effects (bar statics).
Unfortunately, I don't really see any good way to avoid this.
The big problem with stateless calls with no side-effects is that the
API is not extensible. As I add new options, especially algorithm-
specific options, it is increasingly painful (and non-reentrant) to do
this via global functions (set_stochastic_population) with side-
effects. And it is also painful for the user to call a function like
nlopt_minimized_econstrained with a zillion parameters, most of which
are not needed most of the time, and for me to keep adding more
functions with more parameters ... not only is the resulting code not
very readable (if you have a function with 25 parameters like
nlopt_minimized_econstrained, it is hard to see which refers to what),
but also I'm finding that users are confused because they don't
realize that they can just specify harmless default values for most of
the parameters (e.g. for most of the stopping criteria).
When I first started NLopt, I was only thinking I would include bound-
constrained optimization, so a single function didn't seem so bad.
But as my own optimization needs expanded, so did the library and the
original API is getting out of hand (although I'll include it
indefinitely, if possible, for backwards compatibility).
The alternative is an interface with explicit (opaque) state, where I
can transparently add new options (even algorithm-specific options)
over time as needed in a backwards-compatible way, and the user only
need call functions to set those options that are needed in a
particular optimization run. The opt datatype has to have dynamic
allocation for a variety of reasons (e.g. the upper and lower bounds
are arrays of length of the dimension of the problem), and hence must
have a destroy function.
This also maps a bit more cleanly to a C++ interface, and in fact I'll
be providing a C++ nlopt.hpp header file that wraps an nlopt::opt
object around nlopt_opt and allows you to pass std::vector<double>
etcetera (although the objective function will still be C-like). Of
course, with the C++ object, there is no need to call an explicit
deallocation function since this is called by the object's destructor
when it goes out of scope.
(The other motivation to do this is to eventually use SWIG to map the C
++ object onto a Python API, a Java API, etcetera.)
Steven
_______________________________________________
NLopt-discuss mailing list
[email protected]
http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/nlopt-discuss