| 344 | return f, grad, lb, ub |
| 345 | |
| 346 | def solve(self) -> Tuple[Sequence[Sequence[float]], Dict[str, Any]]: |
| 347 | |
| 348 | x0 = array(list(chain.from_iterable(self.entities))).ravel() |
| 349 | f, grad, lb, ub = self._cost(x0) |
| 350 | |
| 351 | def func(x, g): |
| 352 | |
| 353 | if g.size > 0: |
| 354 | grad(x, g) |
| 355 | |
| 356 | return f(x) |
| 357 | |
| 358 | opt = nlopt.opt(nlopt.LD_SLSQP, len(x0)) |
| 359 | opt.set_min_objective(func) |
| 360 | opt.set_lower_bounds(lb) |
| 361 | opt.set_upper_bounds(ub) |
| 362 | |
| 363 | opt.set_ftol_abs(0) |
| 364 | opt.set_ftol_rel(0) |
| 365 | opt.set_xtol_rel(TOL) |
| 366 | opt.set_xtol_abs(TOL * 1e-3) |
| 367 | opt.set_maxeval(MAXITER) |
| 368 | |
| 369 | x = opt.optimize(x0) |
| 370 | status = { |
| 371 | "entities": self.entities, |
| 372 | "cost": opt.last_optimum_value(), |
| 373 | "iters": opt.get_numevals(), |
| 374 | "status": opt.last_optimize_result(), |
| 375 | } |
| 376 | |
| 377 | ixs = self.ixs |
| 378 | |
| 379 | return [x[i1:i2] for i1, i2 in zip(ixs, ixs[1:])], status |