2013-05-29 15 views

risposta

6

Sì, è possibile.

C'è un bel submission on the file exchange che ti permette di fare esattamente questo. Funziona approssimando la curva con un polinomio Chebychev, e quindi trovando tutte le radici reali di quel polinomio.

Se si desidera è possibile utilizzare queste stime per le radici come valori iniziali per fzero, ma spesso (almeno per regolare e in caso contrario le curve ben educati) le richieste di accuratezza possono già essere soddisfatte utilizzando un ordine superiore Chebychev approssimazione .

Per esempio, utilizzando solo 18 valutazioni di funzione (ho una versione leggermente modificata del file, ma la sostanza è la stessa):

>> f = @(A) 17.7*sin(A).*cos(A)+87*sin(A).^2-9.65*cos(A)-47*sin(A); 
>> R = FindRealRoots(f, -5,5, 17) 
R = 
    -3.709993256346244 
    -3.345207732130925 
    -0.201929737187637 
    0.572382702285053 
    2.573423209113534 
    2.937157987217741 

>> R2 = R; 
>> funcCount = 0; 
>> for ii = 1:numel(R) 
     [R2(ii), ~,~, output] = fzero(f,R2(ii)); 
     funcCount = funcCount + output.funcCount; 
    end 
>> max(abs(R2(:)-R(:))) 
ans = 
    8.564253235401331e-004 
>> funcCount 
ans = 
    46 

ad esempio, c'è solo 8 parti per diecimila miglioramento per non meno di 46 valutazioni di funzioni aggiuntive.

+0

@RobertP .: Nessuno, che io sappia ... che è un po 'strano, dal momento che [polinomi Chebychev] (http://en.wikipedia.org/wiki/Chebyshev_polynomials) sono la scelta migliore per approssimazioni polinomiali. In effetti, almeno per il tipo di funzione con cui si ha a che fare (liscio, continuo, ecc.), La precisione può essere abbastanza elevata. L'unico inconveniente è che può essere difficile scegliere valori "buoni" di 'n' (è qui che la funzione di tracciamento integrata è utile). –

+1

+1 per suggerire i polinomi di Chebychev, li ho trovati molto utili in molti aspetti del calcolo. – bla

2

primo luogo v'è di Matlab costruito in opzione che utilizza la matematica simbolica cassetta degli attrezzi: mathworks.com/help/symbolic/mupad_ref/numeric-realroots.html

Un'altra opzione, se la funzione è ben comportata, è solo per alimentare fsolve con le congetture giuste, quindi, anche se sta usando una loop, è un calcolo efficiente. Per esempio:

A=linspace(-5,5,1000); 
[email protected](A) 17.7.*sin(A).*cos(A)+87.*sin(A).^2-9.65*cos(A)-47*sin(A) 

idx = find(diff(sign(f(A)))); 
for n=1:numel(idx) 
    r(n)=fzero(f,A(idx(n))) 
end 

r= 
    -3.709541990613713 
    -3.345170894638306 
    -0.202018624930518 
    0.572128202319968 
    2.573643316565874 
    2.938014412541281 
+0

Grazie a @natan! Non conoscevo 'numeric :: realroots'. Anche la seconda soluzione è stata bella! =) –