ImportC and #include files
jmh530
john.michael.hall at gmail.com
Thu May 11 16:52:11 UTC 2023
On Monday, 8 May 2023 at 13:22:44 UTC, jmh530 wrote:
> [snip
> I was able to get nlopt's tutorial example working with
> importC. I can write a bit more up later.
>
For some more details, in case anyone is interested (and myself
in case I forget and need to search for it in the future). I
installed nlopt as a shared library to some random location (I
had to use cmake to disable installation of some parts, like how
it handles python). I started with the tutorial [1] and put
together a C version of the example and compiled with gcc using
```
gcc cversion.c -w -lnlopt -lm -L/usr/local/nlopt/nlopt/build/
-Wl,-rpath=/usr/local/nlopt/nlopt/build/ -o myprogram
```
The -Wl,rpath is because I didn't install the shared library into
a usual location for shared libraries. How to actually do this in
practice depends on how you install it and whether to use shared
or static libraries. Regardless, I think it is good to get the C
version working first.
I then created two .c files one that just includes nlopt.h and
another that just includes math.h (as bachmeier recommends) and
adjusted the C version of the tutorial to a D version (see below)
and compiled with
```d
dmd dversion.d math.c nlopt.c -of=dversion -L-lnlopt
-L--rpath=/usr/local/nlopt/nlopt/build/
```
dversion.d
```d
import math;
import nlopt;
extern(C)
double myfunc(uint n, const double* x, double* grad, void*
my_func_data)
{
if (grad) {
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}
struct my_constraint_data
{
double a, b;
}
extern(C)
double myconstraint(uint n, const double* x, double* grad, void*
data)
{
my_constraint_data* d = cast(my_constraint_data*) data;
double a = d.a, b = d.b;
if (grad) {
grad[0] = 3 * a * (a*x[0] + b) * (a*x[0] + b);
grad[1] = -1.0;
}
return ((a*x[0] + b) * (a*x[0] + b) * (a*x[0] + b) - x[1]);
}
void main() {
import core.stdc.stdio: printf;
import core.stdc.math: HUGE_VAL;
double[2] lb = [-HUGE_VAL, 0]; /* lower bounds */
nlopt_opt opt;
opt = nlopt_create(NLOPT_LD_MMA, 2); /* algorithm and
dimensionality */
nlopt_set_lower_bounds(opt, lb.ptr);
nlopt_set_min_objective(opt, &myfunc, null);
my_constraint_data[2] data = [{2,0}, {-1,1}];
nlopt_add_inequality_constraint(opt, &myconstraint, &data[0],
1e-8);
nlopt_add_inequality_constraint(opt, &myconstraint, &data[1],
1e-8);
nlopt_set_xtol_rel(opt, 1e-4);
double[2] x = [1.234, 5.678]; /* `*`some` `initial`
`guess`*` */
double minf = void; /* `*`the` `minimum` `objective` `value,`
`upon` `return`*` */
if (nlopt_optimize(opt, x.ptr, &minf) < 0) {
printf("nlopt failed!\n");
}
else {
printf("found minimum at f(%g,%g) = %0.10g\n", x[0],
x[1], minf);
}
nlopt_destroy(opt);
}
```
[1]
https://github.com/stevengj/nlopt/blob/master/doc/docs/NLopt_Tutorial.md
More information about the Digitalmars-d
mailing list