Below is the root search algorithm code I wrote in college. This is written in octave. It's simple to understand and re-write in C++.
Develop numerical methods algos as a separate module and integrate with your pricing and other code
I want to WARN you to re-check for bugs. It always converges for my objective functions
First function is Dekker method similar to Brent. Brent is more better. Second function is bracketing method. Either one can be used for root search
##
## 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