Matlab中能否从fminsearch获取Jacobian?求可行解决方法
Hey there! I get why you'd want a Jacobian output similar to lsqnonlin—it's super handy for post-optimization analysis. Let's break down the core issue first, then walk through practical solutions:
Why fminsearch doesn't return a Jacobian
fminsearch relies on the Nelder-Mead simplex method, which is a derivative-free optimization algorithm. It never computes or stores Jacobian/gradient information during its process—so setting 'Jacobian','on' in optimset has no effect here. That option is only designed for derivative-based solvers like fminunc or lsqnonlin, which actively use Jacobian data to guide optimization.
Solutions to get Jacobian information
1. Compute a numerical Jacobian manually after optimization
Since fminsearch gives you the optimized parameters, you can calculate a numerical Jacobian using finite differences. Here's a quick implementation tailored for residual-based functions (like you'd use with lsqnonlin):
function jacobian = compute_numerical_jacobian(residual_fun, x_opt, epsilon) num_params = length(x_opt); residual_base = residual_fun(x_opt); num_residuals = length(residual_base); jacobian = zeros(num_residuals, num_params); for i = 1:num_params % Perturb the i-th parameter slightly x_perturbed = x_opt; x_perturbed(i) = x_perturbed(i) + epsilon; % Calculate perturbed residual residual_perturbed = residual_fun(x_perturbed); % Finite difference approximation for the column jacobian(:, i) = (residual_perturbed - residual_base) / epsilon; end end % Usage example after running fminsearch: [x_opt, fval, exitflag, output] = fminsearch(@your_residual_fun, x0, options); jacobian = compute_numerical_jacobian(@your_residual_fun, x_opt, 1e-6);
Tweak epsilon based on your problem's scale—smaller values aren't always better, as they can introduce numerical noise.
2. Switch to a derivative-based solver (if feasible)
If your problem allows it, use lsqnonlin (for least-squares problems) or fminunc (for general unconstrained optimization) instead. These solvers natively support computing and returning Jacobians when you enable the 'Jacobian' option. For example:
options = optimset('MaxFunEvals',100,'Jacobian','on'); [x, residualsNorm, residual, exitflag, output, lambda, jacobian] = lsqnonlin(@your_residual_fun, x0, lb, ub, options);
This is the most straightforward approach if derivative-based optimization works for your problem.
内容的提问来源于stack exchange,提问作者Adnan j

