Generated banner for Matlab Solve Optimization
Generated logo for Matlab Solve Optimization

Matlab Solve Optimization

MathWorksOfficialCreated by MathWorks

  • Skill
  • Tool integration
  • Science and research
  • BSD-2-Clause
  • No issues found

From the author

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.
— the description by MathWorks

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured workflow for the entire optimization lifecycle in MATLAB. It covers problem classification, formulation using both problem-based and solver-based approaches, solver selection, configuration, and result validation. It emphasizes best practices for using tools like optimproblem, fcn2optimexpr, and various solvers, while providing guidance on debugging convergence issues and ensuring numerical correctness.

What it does

  • Classifies optimization problems to select the appropriate solver and guarantee level.
  • Guides the formulation of problems using the problem-based framework (optimvar, optimproblem).
  • Provides templates for solver-based approaches when specific API control is required.
  • Offers strategies for solver configuration, including tuning and parallelization.
  • Details methods for validating results, checking convergence, and verifying constraint satisfaction.
  • Provides debugging checklists for failed optimizations and performance optimization techniques.

When to use it

  • When defining decision variables, objectives, and constraints for a mathematical model.
  • When selecting or configuring solvers like fmincon, linprog, or ga.
  • When interpreting solver exitflags or debugging convergence failures.
  • When deciding between problem-based and solver-based modeling approaches.
  • When writing optimization code that requires robust validation and performance tuning.

Advantages

  • Promotes a standardized, repeatable workflow for optimization tasks.
  • Reduces common errors by providing clear templates and validation steps.
  • Helps identify the most efficient solver for specific problem structures.
  • Provides clear guidance on when to use advanced features like automatic differentiation.
  • Includes practical debugging strategies for common numerical and formulation issues.

Usage examples

“How do I define a constrained optimization problem in MATLAB using the problem-based approach?”
The agent provides a template using optimvar to define variables, optimproblem to set the objective, and adding constraints to prob.Constraints, followed by the solve command.
“My fmincon optimization is not converging. How should I debug it?”
The agent suggests checking the exitflag, verifying the objective and constraints at the initial guess, checking gradient accuracy, and reviewing the scaling of variables.
“Should I use fmincon or patternsearch for my nonlinear problem?”
The agent guides the user to check if gradients are available and reliable; if so, fmincon is preferred, otherwise patternsearch is recommended for derivative-free optimization.
“How do I wrap a complex simulation function for use in an optimization problem?”
The agent explains how to use fcn2optimexpr to wrap the function, noting whether to treat it as a black-box or allow automatic differentiation.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/matlab/matlab-solve-optimization/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip matlab-solve-optimization.zip -d .agents/skills

Documentation by MathWorks

MATLAB Optimization Workflow

Guide the full optimization lifecycle: classify the problem, formulate it, select and configure a solver, and validate the results.

When to Use

  • User is defining an optimization problem in MATLAB (variables, objectives, constraints)

  • User asks about optimproblem, optimvar, optimconstr, optimexpr, or fcn2optimexpr

  • User is selecting or configuring a solver (optimoptions, algorithm choice, tuning)

  • User is interpreting results, debugging convergence, or checking exitflags

  • User is deciding between problem-based and solver-based approaches

  • User is writing optimization code with for-loops over decision variables or constraints

When NOT to Use

  • User is asking to solve a problem that doesn't require numerical optimization solvers (e.g., finding the minimum value in an array or table)

  • User is working with non-optimization MATLAB code (data analysis, plotting, signal processing)

  • User is using a third-party optimization toolbox (not MathWorks)

  • User is solving symbolic equations with solve(eqns, vars), ODE systems, or linear system solves (A\b)


Stage 1: Classify & Formulate

1.1 Classify the Problem

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:

  • Check if a purpose-built domain tool exists before falling back to optimproblem

  • Watch for hidden easier classes (sum-of-squares disguised as NLP, linear structure missed)

  • For QPs, check eig(H) — nonconvex QPs cannot use quadprog reliably

  • Watch for hidden nonsmoothness: max, min, abs, sort, if/branching, or norms other than squared-2-norm

1.2 Choose Approach

Use 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/HessianNo benefit from abstraction; solver-based is direct
Overhead of building problem-based expressions dominates computationAvoid 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 requiredProblem-based does not support codegen

Converting between approaches: prob2struct(prob) converts problem-based to solver-based form for deployment or performance.

References:

1.3 Formulate the Problem

Problem-based canonical template:

% 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:

  • Initial guess is a numeric vector, not a struct

  • You manage variable indexing manually (flat vector x)

  • Supply gradients manually for best performance (SpecifyObjectiveGradient=true)

  • Linear/quadratic solvers require explicit coefficient matrices

1.4 Validate at the Start Point

Before calling any solver, evaluate the objective and constraints at x0 to catch sign/size/NaN errors early:

% 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.


Stage 2: Select & Configure Solver

2.1 Select the Narrowest Solver

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:

  • Always prefer: linprog > quadprog > coneprog > lsqlin > lsqnonlin > fmincon > global solvers

  • Always prefer fminunc over fminsearch when Optimization Toolbox is installed

  • Always prefer lsqnonlin/lsqcurvefit over fmincon for least-squares problems

  • Always prefer lsqlin over lsqnonlin for linear least-squares with bounds or linear constraints

  • Use patternsearch when gradients are unavailable/unreliable AND the problem is not extremely expensive

  • Use surrogateopt when each evaluation takes >15-20 seconds

  • For nearly linear MIPs, linearize and use intlinprog rather than calling Global Optimization solvers

  • For unit commitment / binary operating modes, keep mixed-integer with intlinprog

See references/classify.md for the full class→solver table.

2.2 Verify Options — Never Guess

ALWAYS verify that solver options are valid before using them. Options change across MATLAB releases and hallucinated options cause runtime errors.

% 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.

2.3 Verify Gradients (if supplied)

If analytic gradients are supplied (SpecifyObjectiveGradient=true), verify them before solving:

[valid, err] = checkGradients(@myObjective, x0, Display="on");

For constraint gradients: checkGradients(@myConstraints, x0, IsConstraint=true).

2.4 Parallelize (if expensive)

If the solver supports UseParallel and Parallel Computing Toolbox is available:

ver('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.

2.5 Performance (after correctness)

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.


Stage 3: Validate Results

3.1 Basic Validation (Always Include)

Every time solver-calling code is written, add basic output validation:

[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.

3.2 Extended Validation

Constraint violations (problem-based):

[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):

if 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
3.3 Debugging Failed or Poor Solutions

When exitflag <= 0 or convergence is poor, follow the improving-results checklist in references/improving-results.md:

  1. Check formulation — constraints feasible? bounds consistent? objective well-defined at x0?

  2. Check scaling — scale variables to O(1); rescale if objective/constraints differ by orders of magnitude; use FiniteDifferenceType='central' if finite-difference gradients are inaccurate

  3. Try different algorithms — options.Algorithm, increase MaxIterations/MaxFunctionEvaluations, adjust tolerances, set HybridFcn for heuristic solvers

  4. Try different initial points — MultiStart, GlobalSearch, or surrogateopt/ga for global optimization

Debug discipline:

  • Smallest-first. Shrink to 2-3 variables. A bug in a toy problem is minutes; at full scale is hours.

  • One change at a time, justified by a symptom.

  • Stop-and-ask budget. Stop coding and talk to the user when: >3 rounds with no improvement, >2 option tweaks that don't move diagnostics, or you can't get a finite objective at x0 even on a toy problem.

3.4 Application-Specific Visualization
Problem DomainSuggested Plots
Optimal control / navigationState trajectories vs time, control input profiles, phase portraits
Scheduling / assignmentGantt charts, resource utilization over time
Design optimizationContour plots with optimum marked, sensitivity plots
Parameter estimation / fittingResidual plots, fitted surface vs data
Portfolio / allocationBar charts of allocations, efficient frontier plots

Gotchas

Formulation
  1. Initial guess must be a struct with field names matching optimvar names exactly. NOT a flat vector.

  2. Do NOT set SpecifyObjectiveGradient or SpecifyConstraintGradient in options for problem-based — AD manages gradients internally.

  3. Use N-D optimvar for multi-dimensional problems. Do NOT create scalar variables in a loop.

  4. Preallocate constraint arrays with optimconstr(N). Do NOT concatenate in a loop.

  5. Call fcn2optimexpr ONCE per function, not inside loops. See references/fcn2optimexpr-guide.md.

  6. Use "like" for preallocation inside traced functions to preserve AD type: zeros(n,1,"like",x).

Solver Configuration
  1. Never guess option names from memory. Always verify with optimoptions('solvername').

  2. Do NOT tighten MeshTolerance for patternsearch too much.

  3. Do NOT set AbsoluteGapTolerance/RelativeGapTolerance high for intlinprog for early stopping — use time/node limits.

  4. Keep tolerances well above machine epsilon. Use 1e-6 to 1e-8 range unless specifically required.

Validation
  1. output.constrviolation does not exist for unconstrained solvers. Always check with isfield.

  2. Do NOT check output.firstorderopt for derivative-free solvers. Check solver-specific metrics instead (output.meshsize, output.stallgenerations).

  3. infeasibility() operates on individual constraints, not entire problems. Use issatisfied(prob, sol) for overall checks.

  4. For fmincon with exitflag <= 0, check output.bestfeasible. Use it as a starting point for a new solve.

Conventions

  • Default to problem-based unless a specific blocker applies.

  • When vectorization is possible, always prefer it over loops.

  • When wrapping complex logic in fcn2optimexpr, encapsulate in a single helper function rather than calling inside a loop.

  • Always show the initial guess setup.

  • Mark code blocks as templates when they depend on user-supplied functions.

  • When suggesting tuning options, explain the trade-off (speed vs accuracy).

  • Do not over-tune: for simple or small problems, defaults are usually sufficient.

  • Always include basic validation (exitflag check) when writing solver-calling code.

  • When debugging, start with formulation and scaling before changing algorithms.


Copyright 2026 The MathWorks, Inc.

Files

references/improving-results.md

Improving Optimization Results

Systematic debugging guide for failed or poor-quality optimization results.

Doc reference: https://www.mathworks.com/help/optim/improving-results.html

Debugging Workflow

When an optimization fails to converge or produces a poor solution, work through these steps in order:

1. Check Problem Formulation

Common formulation errors:

Infeasible constraints:

  • Are the constraints mathematically consistent?

  • Is the initial guess feasible?

Test for feasibility:

% Problem-based
infeas_at_x0 = infeasibility(prob.Constraints, x0);
fprintf('Infeasibility at initial guess: %.3e\n', infeas_at_x0);

% Solver-based
[c0, ceq0] = nonlcon(x0);
fprintf('Inequality violations at x0: max = %.3e\n', max([c0; 0]));
fprintf('Equality violations at x0: max = %.3e\n', max(abs(ceq0)));

Unbounded problems:

  • Does the objective have a finite minimum?

  • Are there missing constraints that should bound the solution?

Ill-defined objectives:

  • Does the objective function error at x0?

  • Does it return NaN or Inf for some inputs?

Feasibility-only solve (problem-based):

% Replace objective with a constant — solve() just seeks feasibility
probFeas = prob;
probFeas.Objective = 0;
[sol, ~, ef] = solve(probFeas, x0struct);
% ef > 0: constraints ARE compatible (bug is elsewhere)
% ef < 0 for NLP: may mean "couldn't reach feasible from THIS x0" — retry from other starts

EnableFeasibilityMode (fmincon, smooth NLP): If the standard solve reports infeasible, try putting more effort into reaching feasibility:

opts = optimoptions('fmincon', EnableFeasibilityMode=true, SubproblemAlgorithm="cg");

Confirm this option exists for the user's release with optimoptions('fmincon') before relying on it.

Relaxation strategy (slack variables): If constraints appear infeasible, find which group conflicts:

% Add slack s >= 0 to each inequality, minimize sum(s)
s = optimvar('s', nConstraints, 'LowerBound', 0);
probSlack = prob;
probSlack.Objective = sum(s);
% Relax: g(x) <= b becomes g(x) - s <= b
% Nonzero s_i at optimum → constraint i is part of the infeasibility
1b. NaN/Inf During Solve

If the solver produces NaN or Inf mid-run, the objective/constraint is undefined somewhere the solver stepped (e.g., log/sqrt/division by a variable that went ≤ 0).

Fix: Add bounds that keep arguments valid, and switch to the sqp algorithm — unlike the default interior-point, sqp evaluates only at points satisfying the bounds every iterate, so it won't step where log/sqrt are undefined.

Important: A bound at the singular value (lb = 0 for log(x)) is not enough — the function is still undefined on the bound. Offset it: lb = eps or a small physical floor.

options = optimoptions('fmincon', Algorithm='sqp');
% Ensure lb > 0 for log/sqrt arguments
lb(log_vars) = eps;
2. Check Scaling and Numerical Conditioning

Poor scaling is a top cause of convergence failure. Variables, objectives, and constraints should all be O(1) in magnitude.

Diagnosis:

  • Are decision variables vastly different in scale? (e.g., x1 in [0, 1] and x2 in [1e6, 1e9])

  • Does the objective vary by orders of magnitude across the feasible region?

  • Do constraints have vastly different magnitudes?

Fixes:

Rescale variables:

% Original: x in [0, 1e6]
% Scaled: y in [0, 1], x = 1e6 * y
% Reformulate objective and constraints in terms of y

Rescale objective and constraints:

% If objective is O(1e8), divide by 1e8
% If constraint is A*x <= 1e-6, multiply by 1e6

Adjust finite-difference step size: If gradients are inaccurate due to scaling:

options = optimoptions('fmincon',FiniteDifferenceType="central");

Condition number and definiteness check: For quadratic problems with quadprog, check the condition number and positive definiteness of H:

cond_H = cond(H);
if cond_H > 1e12
    warning('Hessian is ill-conditioned (cond = %.3e). Consider rescaling.\n', cond_H);
end

% Check positive definiteness
try
    chol(H);
    fprintf('H is positive definite.\n');
catch
    warning('H is not positive definite. Check eigenvalues:\n');
    eig_H = eig(H);
    fprintf('  Min eigenvalue: %.3e\n  Max eigenvalue: %.3e\n', min(eig_H), max(eig_H));
    fprintf('A positive semi-definite or indefinite Hessian may cause stalling or divergence.\n');
end
3. Tune Solver Options and Algorithms

Try a different algorithm:

Most solvers support multiple algorithms. Consult the solver's documentation for available options. For example:

% Example: try 'sqp' algorithm for fmincon
opts_sqp = optimoptions('fmincon', 'Algorithm', 'sqp');
[x, fval] = fmincon(fun, x0, A, b, Aeq, beq, lb, ub, nonlcon, opts_sqp);

Increase iteration/evaluation limits (only if still progressing):

Before raising limits, check if the solver is actually making progress — run with Display='iter' and watch whether the objective and firstorderopt are still decreasing. If they've gone flat for ~10+ iterations, more iterations won't help — the cause is scaling, formulation, or a wrong gradient. Only raise limits if the solver is still improving.

options = optimoptions('fmincon', ...
    'MaxIterations', 1000, ...
    'MaxFunctionEvaluations', 5000);

Hybrid function for solution polishing: For derivative-free solvers (ga, gamultiobj, patternsearch, particleswarm), use HybridFcn to refine the final solution with a gradient-based method:

options = optimoptions('ga', 'HybridFcn', @fmincon);

Adjust tolerances:

% Tighten for more accurate solution
options = optimoptions('fmincon', ...
    'OptimalityTolerance', 1e-8, ...
    'ConstraintTolerance', 1e-8, ...
    'StepTolerance', 1e-10);

% Loosen if struggling to converge
options = optimoptions('fmincon', ...
    'OptimalityTolerance', 1e-4, ...
    'ConstraintTolerance', 1e-4);
4. Try Different Initial Points

For nonlinear problems, the initial guess strongly affects:

  • Which local minimum is found

  • Whether the solver converges at all

Strategies:

Manual exploration: Try several initial guesses based on domain knowledge:

x0_candidates = [x0_default, x0_midpoint, x0_boundary, x0_random];
for i = 1:size(x0_candidates, 2)
    [x, fval, exitflag] = fmincon(fun, x0_candidates(:,i), ...);
    fprintf('Initial guess %d: exitflag=%d, fval=%.6f\n', i, exitflag, fval);
end

Multi-start: Automatically run from multiple starting points and select the best. Choose the start-points based on the problem dimensionality, but not too large — never open-end a multi-start search:

ms = MultiStart;
problem = createOptimProblem('fmincon', 'objective', fun, 'x0', x0, ...
    'Aineq', A, 'bineq', b, 'lb', lb, 'ub', ub, 'nonlcon', nonlcon, ...
    'options', optimoptions('fmincon'));
[x, fval] = run(ms, problem, 50);  % 50 random start points

For problem-based:

ms = MultiStart;
[sol, fval] = solve(prob, x0, ms, 'MinNumStartPoints', 30);

Global optimization: If the problem has many local minima and you need a global solution:

  • surrogateopt — surrogate-based, good for expensive objectives

  • ga — genetic algorithm, handles integer and nonlinear

  • particleswarm — particle swarm, good for continuous problems

  • GlobalSearch — multistart with clustering and basin-hopping

opts = optimoptions('surrogateopt', ...
    'MaxFunctionEvaluations', 500, ...
    'MinSurrogatePoints', 10*(nvars+1));  % Increase initial random samples
[x, fval] = surrogateopt(fun, lb, ub, opts);

For surrogateopt, you can also provide initial points and pre-computed function values:

opts = optimoptions('surrogateopt', 'InitialPoints', x0_matrix);
% where x0_matrix is a matrix with each row being an initial point
5. Verify Gradient Accuracy

Inaccurate gradients (when using finite differences or analytical gradients) can cause convergence failure.

Check gradient accuracy: Use checkGradients to verify analytical gradients. Note: checkGradients requires a named function (not an anonymous function) that returns [f, grad] as two outputs:

% Define objective function that returns both value and gradient
function [f, grad] = myObjective(x)
    f = x(1)^2 + 2*x(2)^2;
    grad = [2*x(1); 4*x(2)];
end

% Check gradients at initial point
[valid, err] = checkGradients(@myObjective, x0, Display="on");
if ~valid
    warning('Gradient check failed. Review analytical gradient implementation.');
end

For constraint gradients, use IsConstraint=true:

[valid, err] = checkGradients(@myConstraints, x0, IsConstraint=true, Display="on");

If analytical gradients are incorrect, either:

  • Fix coding errors in the gradient function

  • Switch to finite differences if the scale is very large or small

For finite-difference gradients with poor accuracy due to scaling:

options = optimoptions('fmincon', 'FiniteDifferenceType', 'central');

Central differences are more accurate than forward differences but require twice as many function evaluations.

For problem-based, let automatic differentiation compute gradients (preferred over manual finite differences).

6. Inspect Solver Progress

Enable iterative display to monitor convergence:

options = optimoptions('fmincon', 'Display', 'iter');

Use 'PlotFcn' to visualize solver progress:

options = optimoptions('fmincon', ...
    'Display', 'iter', ...
    'PlotFcn', {@optimplotfval, @optimplotfirstorderopt, @optimplotconstrviolation});

What to look for:

  • Oscillation: Objective or constraint violations oscillate without improving — consider tightening tolerances or switching algorithm

  • Stalling: Objective plateaus for many iterations — may be at a local minimum, or step size is too small

  • Early termination: Solver stops after just a few iterations — check if initial guess is already optimal or if constraints are immediately violated

Custom output function:

options = optimoptions('fmincon', 'OutputFcn', @myOutputFcn);

function stop = myOutputFcn(x, optimValues, state)
    stop = false;
    if strcmp(state, 'iter')
        fprintf('Iter %d: fval=%.6f, constrViolation=%.3e\n', ...
            optimValues.iteration, optimValues.fval, optimValues.constrviolation);
    end
end
7. Validate Regularization

If regularization was introduced (e.g., Tikhonov, L2 penalty, smoothing), verify it actually helps:

  1. Report the baseline: Solve and record the unregularized metric first.

  2. Test at least one nonzero level: Try one or more nonzero regularization parameters.

  3. Publish the best defensible result: Keep the regularization level with the best metric you can defend.

  4. If regularization doesn't help, say so: If no regularization level improves the defended metric, keep the unregularized result and state that explicitly.

Do not claim a larger regularization parameter is better just because the solution looks smoother. Publish the result that validates best under the metric you can defend.

lambdas = [0, 1e-4, 1e-3, 1e-2];
bestIdx = 1;
bestMetric = inf;
for k = 1:numel(lambdas)
    % Solve with regularization level lambdas(k)
    % ...
    metric = computeValidationMetric(solution);
    if metric < bestMetric
        bestMetric = metric;
        bestIdx = k;
    end
end
fprintf("Best regularization: lambda = %.1e (metric = %.4f)\n", lambdas(bestIdx), bestMetric);
8. Integer Solve Too Slow (MILP/MIQP)

Integer solve time is dominated by the formulation, not solver options. Tighten it:

  • Smaller big-M constants — oversized M values weaken LP relaxations and explode the branch-and-bound tree

  • Tighter variable bounds — every tighter bound prunes branches

  • Valid inequalities — extra constraints that don't cut feasible integer points but tighten the relaxation

  • Warm-start from a known feasible solution where supported

Set a relative-gap or time limit and accept the best incumbent when a proven optimum isn't worth the wait:

options = optimoptions('intlinprog', ...
    RelativeGapTolerance=0.01, ...  % accept 1% gap
    MaxTime=600);                    % or 10-minute cap

If the problem is MIQP/MINLP with no exact solver (intlinprog is linear-only), reformulate to MILP or switch to ga/surrogateopt (heuristic — report it as such).

9. Nonsmooth Objective Detected

If the objective or constraints contain abs, max, min, sorting, or if branches, gradient-based solvers will struggle (they assume smoothness).

Options:

  • Reformulate the nonsmooth term into a smooth/LP/QP form (e.g., minimax → epigraph trick, abs → auxiliary variables). This often turns the problem convex.

  • Switch to a derivative-free solver (patternsearch, surrogateopt) that doesn't need gradients.

Reformulating is usually better — it moves the problem to an easier class with stronger guarantees.

Checklist Summary

When debugging a failed optimization:

  • [ ] Formulation: Is the problem well-posed? Are constraints feasible?

  • [ ] Scaling: Are variables, objective, and constraints O(1)?

  • [ ] Algorithm: Have you tried alternative algorithms?

  • [ ] Tolerances: Are they appropriate for your problem?

  • [ ] Initial guess: Have you tried multiple starting points?

  • [ ] Gradients: Are finite-difference gradients accurate?

  • [ ] Progress: Have you inspected the solver's iteration history?

Work through this list systematically. Most convergence issues fall into the first three categories.


Copyright 2026 The MathWorks, Inc.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs Node.js

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
MathWorks
Publisher
MathWorks (Official)
Source
matlab/matlab-agentic-toolkit · skills-catalog/math-and-optimization/matlab-solve-optimization · commit 2a7f215
Licence
BSD 2-Clause License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE.md)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by MathWorks.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-solve-optimization.zip