Fastest method to solve multiple nonlinear independent equations in MATLAB?

Viewed 3868

MATLAB has two methods to solve a nonlinear equation:

  • fzero: solves a single nonlinear equation
  • fsolve: solves a system of nonlinear equations

Therefore, one can use the following methods to solve a system of n nonlinear independent equations:

  1. Use a loop to solve the equations separately using fzero
  2. Use a loop to solve the equations separately using fsolve
  3. Use fsolve to solve them together

My intuition would be that:

  • A loop method is faster than a single system for large n as complexity (gradient calculation) is 0(n^2)
  • A loop may be slower for small n as a loop has a high overhead in MATLAB and there may be some constant startup time
  • fzero is faster than fsolve as it is specifically made for a single nonlinear equation.

Question: What is the fastest method to a system of n nonlinear independent equations? Are there other methods? Which options should be used to speed up the process?

Example problem: (may be used to benchmark different answers)

x_i^2 = 1

with i between 1 and n

Related threads

2 Answers

I'm adding this answer to elaborate on my comment above. In my experience by far the fastest method is to use a vectorized version of fzero that is available on the file exchange: Link to vectorized bisection code

Here is a couple of benchmarks comparing it's performance to (i) looped fzero and (ii) independent fsolve.

f = @(x) x.^2-1; %the set of non-linear equations
ns = 1e5; %size of the problem

% method 1: looped fzero
t = timeit(@() fzero(f, rand(1)));
loopFZero = t*ns

% method 2: independent fsolve
options=optimset('Display','off'); % disable displaying
options.Algorithm = 'trust-region-reflective';
options.JacobPattern = speye(ns);
options.PrecondBandWidth = 0;
indepFSolve = timeit(@() fsolve(f, rand(ns,1), options))

% method 3: vectorized bisection, available here:
% https://www.mathworks.com/matlabcentral/fileexchange/28150-bisection-method-root-finding
vecBisection = timeit(@() bisection(f, zeros(ns,1), 2))

Results

%---------------
% ns = 10

loopFZero =

    0.0027


indepFSolve =

    0.0049


vecBisection =

   5.0978e-05

%---------------
% ns = 1e5

loopFZero =

   28.7574


indepFSolve =

    7.7601


vecBisection =

    0.0013
Related