Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when writing, solving, or debugging MATLAB optimization code — formulating problems (optimproblem, optimvar, fcn2optimexpr), selecting and configuring solvers (fmincon, linprog, quadprog, intlinprog, lsqnonlin, ga, surrogateopt, optimoptions), or validating results (exitflag, convergence, constraint violations). Covers problem-based and solver-based approaches, solver tuning, and solution verification.
.claude/skills/matlab-matlab-solve-optimization/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 239% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 102% | 0% |
| case-20 | ✗→✓ | ▲ Improved | 125% | 0% |
Guide the full optimization lifecycle: classify the problem, formulate it, select and configure a solver, and validate the results.
optimproblem, optimvar, optimconstr, optimexpr, or fcn2optimexproptimoptions, algorithm choice, tuning)solve(eqns, vars), ODE systems, or linear system solves (A\b)Before formulating, identify the problem class — it determines which solver to use, what guarantee you can promise (global vs local), and whether a domain-specific tool should replace the generic path.
See references/classify.md for the class→solver→guarantee table, convexity quick-checks, and "hidden easier class" heuristics. Key actions:
optimproblemeig(H) — nonconvex QPs cannot use quadprog reliablymax, min, abs, sort, if/branching, or norms other than squared-2-normUse problem-based by default for readable definitions, N-D modeling, and every LP, QP, conic, and mixed-integer problem (unless coefficients are already in matrix-vector form). Problem-based provides automatic differentiation and is less error-prone.
Even when AD is blocked (e.g., ode45 in the objective), fcn2optimexpr can still wrap the function as a black-box — problem-based remains useful.
Only fall back to solver-based when one of these applies:
| Use solver-based when... | Reason | |---|---| | Trivial mapping to solver API — one vector x, pre-coded objective with exact gradients/Hessian | No benefit from abstraction; solver-based is direct | | Overhead of building problem-based expressions dominates computation | Avoid tracing/transformation overhead | | Need a solver feature problem-based doesn't expose (CheckpointFile, exact Hessians, custom OutputFcn) | Only available via solver-based calls | | C code generation for embedded deployment is required | Problem-based does not support codegen |
Converting between approaches: prob2struct(prob) converts problem-based to solver-based form for deployment or performance.
References:
Problem-based canonical template:
matlab% 1. Define decision variables x = optimvar("x", N, LowerBound=lb, UpperBound=ub); % 2. Create problem prob = optimproblem("Objective", sum(x,"all")); % 3. Add constraints prob.Constraints.linear = A*x <= b; prob.Constraints.nonlinear = fcn2optimexpr(@myNonlinFcn, x) <= rhs; % 4. Set initial guess (must be struct with field names matching optimvar names) x0.x = initialValues; % 5. Solve [sol, fval, exitflag, output] = solve(prob, x0);
Solver-based key differences:
x)SpecifyObjectiveGradient=true)Before calling any solver, evaluate the objective and constraints at x0 to catch sign/size/NaN errors early:
matlab% Problem-based fval0 = evaluate(prob.Objective, x0); assert(isfinite(fval0), 'Objective is not finite at x0'); infeas0 = infeasibility(prob.Constraints, x0); fprintf('Max infeasibility at x0: %.3e\n', max(infeas0));
For solver-based, call fun(x0) and nonlcon(x0) directly and confirm finite, correctly-sized outputs. If gradients are supplied, run checkGradients at this point.
Choose the narrowest solver that matches the problem structure. Do not default to fmincon or heuristic global solvers when a more specific solver applies.
Key selection rules:
linprog > quadprog > coneprog > lsqlin > lsqnonlin > fmincon > global solversfminunc over fminsearch when Optimization Toolbox is installedlsqnonlin/lsqcurvefit over fmincon for least-squares problemslsqlin over lsqnonlin for linear least-squares with bounds or linear constraintspatternsearch when gradients are unavailable/unreliable AND the problem is not extremely expensivesurrogateopt when each evaluation takes >15-20 secondsintlinprog rather than calling Global Optimization solversintlinprogSee references/classify.md for the full class→solver table.
ALWAYS verify that solver options are valid before using them. Options change across MATLAB releases and hallucinated options cause runtime errors.
matlab% Verify options for a solver opts = optimoptions('solvername')
Run optimoptions('solvername') to see all valid options for the user's installed version before writing options code.
If analytic gradients are supplied (SpecifyObjectiveGradient=true), verify them before solving:
matlab[valid, err] = checkGradients(@myObjective, x0, Display="on");
For constraint gradients: checkGradients(@myConstraints, x0, IsConstraint=true).
If the solver supports UseParallel and Parallel Computing Toolbox is available:
matlabver('parallel') % Check for PCT options = optimoptions('solvername', UseParallel=true);
Solvers supporting UseParallel: fmincon, fminunc, lsqnonlin, lsqcurvefit, patternsearch, surrogateopt, ga, particleswarm, paretosearch, gamultiobj.
Do NOT suggest UseParallel for: quadprog, intlinprog, fminsearch, linprog, lsqlin.
If the solve is correct but too slow, see references/performance-levers.md. Key levers: analytic gradients, sparsity patterns, warm starting, code generation. Apply only after Stage 3 confirms correctness — re-validate after any performance change.
Reference: references/solver-tuning.md for per-solver algorithm and tuning guidance.
Every time solver-calling code is written, add basic output validation:
matlab[sol, fval, exitflag, output] = solve(prob, x0); % Check convergence if exitflag > 0 fprintf('Optimization converged: %s\n', output.message); else warning('Optimization did not converge (exitflag = %d): %s\n', exitflag, output.message); end % Report key metrics fprintf('Objective value: %.6f\n', fval); fprintf('Iterations: %d\n', output.iterations); if isfield(output, 'constrviolation') fprintf('Constraint violation: %d\n', output.constrviolation); end
See references/validation-checklist.md for detailed exitflag meanings per solver.
Constraint violations (problem-based):
matlab[allsat, sat] = issatisfied(prob, sol); if ~allsat conNames = fieldnames(prob.Constraints); for i = 1:numel(conNames) infeas = infeasibility(prob.Constraints.(conNames{i}), sol); if any(infeas > 0) fprintf('Constraint "%s" violated by %.3e\n', conNames{i}, max(infeas)); end end end
Optimality conditions (gradient-based solvers only — skip for patternsearch, ga, particleswarm, surrogateopt):
matlabif isfield(output, 'firstorderopt') fprintf('First-order optimality: %.6e\n', output.firstorderopt); if output.firstorderopt > 1e-3 warning('First-order optimality measure is large — solution may not be optimal.\n'); end end
When exitflag <= 0 or convergence is poor, follow the improving-results checklist in references/improving-results.md:
FiniteDifferenceType='central' if finite-difference gradients are inaccurateoptions.Algorithm, increase MaxIterations/MaxFunctionEvaluations, adjust tolerances, set HybridFcn for heuristic solversMultiStart, GlobalSearch, or surrogateopt/ga for global optimizationDebug discipline:
| Problem Domain | Suggested Plots | |---|---| | Optimal control / navigation | State trajectories vs time, control input profiles, phase portraits | | Scheduling / assignment | Gantt charts, resource utilization over time | | Design optimization | Contour plots with optimum marked, sensitivity plots | | Parameter estimation / fitting | Residual plots, fitted surface vs data | | Portfolio / allocation | Bar charts of allocations, efficient frontier plots |
optimvar names exactly. NOT a flat vector.SpecifyObjectiveGradient or SpecifyConstraintGradient in options for problem-based — AD manages gradients internally.optimvar for multi-dimensional problems. Do NOT create scalar variables in a loop.optimconstr(N). Do NOT concatenate in a loop.fcn2optimexpr ONCE per function, not inside loops. See references/fcn2optimexpr-guide.md."like" for preallocation inside traced functions to preserve AD type: zeros(n,1,"like",x).optimoptions('solvername').MeshTolerance for patternsearch too much.AbsoluteGapTolerance/RelativeGapTolerance high for intlinprog for early stopping — use time/node limits.1e-6 to 1e-8 range unless specifically required.output.constrviolation does not exist for unconstrained solvers. Always check with isfield.output.firstorderopt for derivative-free solvers. Check solver-specific metrics instead (output.meshsize, output.stallgenerations).infeasibility() operates on individual constraints, not entire problems. Use issatisfied(prob, sol) for overall checks.fmincon with exitflag <= 0, check output.bestfeasible. Use it as a starting point for a new solve.fcn2optimexpr, encapsulate in a single helper function rather than calling inside a loop.Copyright 2026 The MathWorks, Inc.
Other measured skills in the registry, with their headline benchmark lift.