1 #include <octave/oct.h>
2 #include <octave/oct-map.h>
8 #include "nlopt_minimize_usage.h"
10 static double struct_val_default(Octave_map &m, const std::string& k,
14 if (m.contents(k).length() == 1 && (m.contents(k))(0).is_real_scalar())
15 return (m.contents(k))(0).double_value();
20 static Matrix struct_val_default(Octave_map &m, const std::string& k,
24 if ((m.contents(k)).length() == 1) {
25 if ((m.contents(k))(0).is_real_scalar())
26 return Matrix(1, dflt.length(), (m.contents(k))(0).double_value());
27 else if ((m.contents(k))(0).is_real_matrix())
28 return (m.contents(k))(0).matrix_value();
39 static double user_function(int n, const double *x,
40 double *gradient, /* NULL if not needed */
43 user_function_data *data = (user_function_data *) data_;
44 octave_value_list args(1 + data->f_data.length(), 0);
46 for (int i = 0; i < n; ++i)
49 for (int i = 0; i < data->f_data.length(); ++i)
50 args(1 + i) = data->f_data(i);
51 octave_value_list res = data->f->do_multi_index_op(gradient ? 2 : 1, args);
52 if (res.length() < (gradient ? 2 : 1))
53 gripe_user_supplied_eval("nlopt_minimize");
54 else if (!res(0).is_real_scalar()
55 || (gradient && !res(1).is_real_matrix()
56 && !(n == 1 && res(1).is_real_scalar())))
57 gripe_user_returned_invalid("nlopt_minimize");
60 if (n == 1 && res(1).is_real_scalar())
61 gradient[0] = res(1).double_value();
63 Matrix grad = res(1).matrix_value();
64 for (int i = 0; i < n; ++i)
65 gradient[i] = grad(i);
68 return res(0).double_value();
73 #define CHECK(cond, msg) if (!(cond)) { fprintf(stderr, msg "\n\n"); print_usage("nlopt_minimize"); return retval; }
75 DEFUN_DLD(nlopt_minimize, args, nargout, NLOPT_MINIMIZE_USAGE)
77 octave_value_list retval;
80 CHECK(args.length() == 7 && nargout <= 3, "wrong number of args");
82 CHECK(args(0).is_real_scalar(), "n must be real scalar");
83 nlopt_algorithm algorithm = nlopt_algorithm(args(0).int_value());
86 CHECK(args(1).is_function() || args(1).is_function_handle(),
87 "f must be function");
88 d.f = args(1).function_value();
89 CHECK(args(2).is_cell(), "f_data must be cell array");
90 d.f_data = args(2).cell_value();
92 CHECK(args(3).is_real_matrix() || args(3).is_real_scalar(),
93 "lb must be real vector");
94 Matrix lb = args(3).is_real_scalar() ?
95 Matrix(1, 1, args(3).double_value()) : args(3).matrix_value();
98 CHECK(args(4).is_real_matrix() || args(4).is_real_scalar(),
99 "ub must be real vector");
100 Matrix ub = args(4).is_real_scalar() ?
101 Matrix(1, 1, args(4).double_value()) : args(4).matrix_value();
102 CHECK(n == ub.length(), "lb and ub must have same length");
104 CHECK(args(5).is_real_matrix() || args(5).is_real_scalar(),
105 "x must be real vector");
106 Matrix x = args(5).is_real_scalar() ?
107 Matrix(1, 1, args(5).double_value()) : args(5).matrix_value();
108 CHECK(n == x.length(), "x and lb/ub must have same length");
110 CHECK(args(6).is_map(), "stop must be structure");
111 Octave_map stop = args(6).map_value();
112 double minf_max = struct_val_default(stop, "minf_max", -HUGE_VAL);
113 double ftol_rel = struct_val_default(stop, "ftol_rel", 0);
114 double ftol_abs = struct_val_default(stop, "ftol_abs", 0);
115 double xtol_rel = struct_val_default(stop, "xtol_rel", 0);
116 Matrix zeros(1, n, 0.0);
117 Matrix xtol_abs = struct_val_default(stop, "xtol_abs", zeros);
118 CHECK(n == xtol_abs.length(), "stop.xtol_abs must have same length as x");
119 int maxeval = int(struct_val_default(stop, "maxeval", -1));
120 double maxtime = struct_val_default(stop, "maxtime", -1);
122 double minf = HUGE_VAL;
123 nlopt_result ret = nlopt_minimize(algorithm,
126 lb.data(), ub.data(),
127 x.fortran_vec(), &minf,
128 minf_max, ftol_rel, ftol_abs,
129 xtol_rel, xtol_abs.data(),
136 retval(2) = int(ret);