O método mais rápido para resolver múltiplas equações independentes não lineares em MATLAB?

MATLAB tem dois métodos para resolver uma equação não linear:

  • fzero: resolve uma única equação não linear
  • fsolve: resolve um sistema de equações não lineares

Portanto, pode-se usar os seguintes métodos para resolver um sistema de equações independentes não lineares:

  1. usar um laço para resolver as equações separadamente usando fzero
  2. usa um laço para resolver as equações separadamente usando fsolve
  3. usar fsolve para os resolver juntos
A minha intuição seria:
  • um método de ciclo é mais rápido do que um sistema único para o Grande n Dado que a complexidade (cálculo do gradiente) é 0 (n^2)
  • um loop pode ser mais lento para o pequeno n como um loop tem uma sobrecarga elevada em MATLAB e pode haver algum tempo de arranque constante
  • fzero é mais rápido que {[1] } porque é feito especificamente para um único não linear Equacao.

pergunta: Qual é o método mais rápido para resolver este problema? Que opções devem ser usadas para acelerar o processo?

tópicos relacionados

Author: m7913d, 2017-07-10

1 answers

A melhor abordagem para avaliar o desempenho de algum método é escrever uma referência. São considerados quatro casos:

  1. loop fzero: usa um loop para resolver as equações separadamente usando fzero
  2. loop fsolve: usa um loop para resolver as equações separadamente usando fsolve
  3. resolução default : resolve as equações juntas como um sistema de equações {[[27]}
  4. resolução independente : igual a predefinição fsolve , mas especifica que as equações são independentes

f = @(x) x.^2-1; % the set of non-linear equations
ns = 1:1:100; % the sizes for which the benchmark is performed
options=optimset('Display','off'); % disable displaying

figure
hold on
plot(ns, loopFSolve(f, ns, options), 'DisplayName', 'loop fsolve')
plot(ns, loopFZero(f, ns, options), 'DisplayName', 'loop fzero')
plot(ns, defaultFSsolve(f, ns, options), 'DisplayName', 'default fsolve')
plot(ns, independentFSolve(f, ns, options), 'DisplayName', 'independent fsolve')

legend ('Location', 'northwest')

function t = loopFZero(f, ns, options)
  t1 = timeit(@() fzero(f, rand(1), options));
  t = ns * t1;
end

function t = loopFSolve(f, ns, options)
  t1 = timeit(@() fsolve(f, rand(1), options));
  t = ns * t1;
end

function t = defaultFSsolve(f, ns, options)
  t = zeros(size(ns));
  for i=1:length(ns)
    n = ns(i);
    un = rand(n, 1);
    t(i) = timeit(@() fsolve(f, un, options));
  end
end

function t = independentFSolve(f, ns, options)
  t = zeros(size(ns));
  for i=1:length(ns)
    n = ns(i);
    un = rand(n, 1);
    options.Algorithm = 'trust-region-reflective';
    options.JacobPattern = speye(n);
    options.PrecondBandWidth = 0;

    t(i) = timeit(@() fsolve(f, un, options));
  end
end

Resultados

Todas as figuras mostram o tempo de cálculo para o sistema completo em função de n, o número de equações.

As duas primeiras figuras plot n até 1000, com um intervalo de 100. As duas últimas figuras plot n até 100 com um intervalo de 1. Para cada um, o segundo lote é o mesmo que o primeiro, mas sem loop fzero como ele é muito mais lento que os outros.

enter image description here enter image description here enter image description here enter image description here Conclusão

  1. loop fsolve : não o utilize, o tempo de arranque é demasiado elevado
  2. loop fzero: pode usá-lo para o small n (método mais rápido para n < ~20)
  3. o fsolve por omissão: pode usá-lo para o relativamente pequeno n (método mais rápido para ~20 < n < ~50, mas a diferença com 2 e 3 é relativa pequeno).
  4. fsolve independente: deve usá-lo para o large n (método mais rápido para ~50 < n)

De um modo geral , deve utilizar fsolve independente , apenas para pequenas n em vez disso, pode utilizar-se o loop fzero, ou seja, utilizar fsolve com as seguintes opções:

options.Algorithm = 'trust-region-reflective';
options.JacobPattern = speye(n);
options.PrecondBandWidth = 0;

As pessoas preguiçosas podem apenas usar o padrão fsolve porque tem um desempenho razoável para um número moderado de equações (n < ~200)

Observações

  • Note que a complexidade temporal da solução por omissãoé O(n^2) enquanto os outros são O(n).
  • Note que fzero e fsolve podem comportar-se de forma diferente em alguns casos limite, F. e fzero não irá encontrar uma solução para x^2 à medida que procura a localização de uma mudança de sinal.
 5
Author: m7913d, 2017-07-11 21:19:42