This assignment teaches implementing simple algorithms with loops and conditionals.
Define a function secant that takes as input
fxloxhidxthat finds a root of f in the interval [xlo:xhi] with a resolution of dx. That is, the function secant should iteratively reduce the size of the interval until it is smaller than dx, bracketing a root of f.
Note:
f(xlo) and f(xhi) have different signfunction secant(f, xlo::Real, xhi::Real, dx::Real)info command to output a message during each iterationsqrt(2) to 100 digits. Hint: Solve x^2-2==0, and use the BigFloat type.
In [1]:
typeof(+)
Out[1]:
In [10]:
midpoint(xlo::Real,xhi::Real)=0.5*(xlo+xhi)
Out[10]:
In [29]:
function secant(f,
xlo::Real,xhi::Real,
dx::Real)
# check various conditions
if xlo == xhi
throw(DomainError())
end
if xlo > xhi
return secant(f,xhi,xlo,dx)
end
flo,fhi = f(xlo),f(xhi)
if sign(flo*fhi) > 0
throw(DomainError())
end
if abs(xlo) <= dx return xlo end
if abs(xhi) <= dx return xhi end
# Initial two guesses based on midpoint method.
x0=midpoint(xlo,xhi)
f0=f(x0)
info("x=$x0 | f=$f0")
if abs(f0) <= dx return x0 end
if f0 < 0
x1 = x0 < 0 ? midpoint(xlo,x0) : midpoint(x0,xhi)
else
x1 = x0 < 0 ? midpoint(x0,xhi) : midpoint(xlo,x0)
end
info("x=$x1 | f=$(f(x1))")
if abs(f(x1)) <= dx return x1 end
# and now the loop!
while abs(f(x1)) > dx
x0,x1 = x1,x1 - f(x1)*(x1-x0)/(f(x1)-f(x0))
info("x=$x1 | f=$(f(x1))")
end
return x1
end
Out[29]:
In [35]:
with_bigfloat_precision(400) do
secant((x)->x^2-2,BigFloat(0.5),BigFloat(2.),BigFloat(10.0^(-100)))
end
Out[35]:
In [ ]: