A continuación está el código del algoritmo de búsqueda de raíces que escribí en la universidad. Está escrito en octava. Es sencillo de entender y reescribir en C++.
Desarrollar algos de métodos numéricos como un módulo separado e integrarlos con su código de precios y otros.
Quiero ADVERTIRTE de que vuelvas a revisar los errores. Siempre converge para mis funciones objetivo
La primera función es el método Dekker, similar al de Brent. Brent es mejor. La segunda función es el método de bracketing. Cualquiera de los dos puede ser utilizado para la búsqueda de root
##
## Dekker root search.
##
## Eg call: dekker(@expMinusOne, -2, 3)
##
function c = dekker(f, lowerBound, upperBound)
MAX_ITER = 50;
iterations = 0;
a = lowerBound;
b = upperBound;
assert(validateBracket(f, a, b), "Given bounds doesn't bracket the root");
assert(!hasMultipleRoots(f, a, b), "Given bounds has mutiple roots");
fa = f(a);
fb = f(b);
#printf("fa = %f, fb = %f\n", fa, fb);
if(abs(fa) < abs(fb))
c = a;
d = b;
else
c = b;
d = a;
endif
linOps = 0;
do
s = linearInterpolation(f, c, d);
m = bisectionPoint(c, d);
a = c;
b = d;
# LI/LE and BI points are on same side of root
if(f(s) * f(m) >= 0)
# New root and lower bound are on same side of the root
# We can adjust one side of the bracket
if(f(c) * f(s) > 0)
if(abs(c - m) < abs(c - s) && linOps < 4)
c = s;
linOps++;
else
c = m;
linOps = 0;
endif
# New root and lower bound are on different sides of the root
# We can adjust both sides of the bracket
else
# Reduce the bracket.
if(abs(c - s) < abs(c - m))
c = s;
else
c = m;
endif
d = a;
endif
# LI/LE and BI points are on different sides of root.
# We can adjust both sides of the bracket
else
if(f(c) * f(s) > 0)
c = s;
d = m;
linOps++;
else
c = m;
d = s;
linOps = 0;
endif
endif
#printf("c = %f, d = %f\n", c, d);
# Check for Convergence
if(c == d)
#printf("DEKKER ROOT = %f in %d iterations.\n", c, iterations);
break;
endif
iterations++;
until (iterations == MAX_ITER)
if(iterations == MAX_ITER)
#printf("DEKKER ROOT = %f for maximum iterations %d.\n", c, MAX_ITER);
endif
endfunction
function s = linearInterpolation(f, a, b)
s = a - (b - a) * f(a)/(f(b) - f(a));
endfunction
function m = bisectionPoint(a, b)
m = (a + b)/2;
endfunction
function r = hasMultipleRoots(f, a, b)
if(f(a) == f(b))
r = true;
else
r = false;
endif
endfunction
function r = validateBracket(f, a, b)
if(f(a) * f(b) < 0)
r = true;
else
r = false;
endif
endfunction
##
## regulaFalsi( f, a, b, yAcc )
##
## rootsearching by regulaFalsi method
##
## f is a real numeric function s.t. f( a ) * f( b ) < 0.0
## xAcc convergence threshold
## nIter max number of iterations
function [c, x] = regulaFalsi( f, a, b, yAcc )
fb = f( b );
fa = f( a );
if ( fa * fb >= 0.0 ),
error(" f( a ) * f( b ) >= 0.0 " );
endif
# init loop variables
c = a;
iter = 1;
x = [];
do
cOld = c; # save previous value of c. Guard for infinite loop
c = a - fa * ( b - a ) / ( fb - fa ); # new point
fc = f( c );
if ( fc * fb < 0.0 ) # update interval
a = c;
fa = fc;
else
b = c;
fb = fc;
endif
x(iter,:)=[iter, c]; iter++; # unnecessary, just for display
until ( abs(fc) < yAcc || cOld == c ) # Exit criteria is on yAcc.
endfunction