by Eugeniy E. Mikhailov and Greg Bentsen
Homework 3 due Monday Sept 21 at 11:59pm
Agenda
Today
Do it at home part
You will be given a task which would require to splice couple covered concepts
Organize yourself in groups of 2 or less
You have almost two weeks to work on assignment
Midterm write up and code is due Sunday October 4th 11:59pm
You may use AI freely to write code, debug, and test.
You are responsible for the code you submit.
We expect you to understand what the code is doing.
You may not use AI to write the report.
In class part
We want to find root of equation () which satisfies
Often it would work a bit different
Which can be moved to canonical form
Example
One can try to get the solution by just guessing with a hope to hit the solution. This is not highly scientific.
However, each guess can provide some clues.
A general algorithm
Works for any continuous function in vicinity of a function root
AI uses prompt in bisection_ai_assignment.txt
#!/usr/bin/env python3
"""
Bisection method implementation.
The function bis(f, x_m, x_p) finds a root of f in the interval [x_m, x_p]
assuming f(x_m) < 0 and f(x_p) > 0.
Parameters:
f: callable, function whose root is to be found.
x_m: float, lower bound of the bracket (f(x_m) < 0).
x_p: float, upper bound of the bracket (f(x_p) > 0).
eps_f: float, tolerance for function value (default 1e-6).
eps_x: float, tolerance for interval width (default 1e-6).
Returns:
x0: float, approximation of the root.
f(x0): float, function value at the root approximation.
"""
def bis(f, x_m, x_p, eps_f=1e-6, eps_x=1e-6):
"""Bisection method to find a root of f in the bracket [x_m, x_p].
The algorithm iteratively narrows the bracket until both the function
value and the bracket width are within the specified tolerances.
Args:
f: callable, function whose root is to be found.
x_m: float, lower bound of the bracket (f(x_m) < 0).
x_p: float, upper bound of the bracket (f(x_p) > 0).
eps_f: float, tolerance for function value (default 1e-6).
eps_x: float, tolerance for interval width (default 1e-6).
Returns:
x0: float, approximation of the root.
f(x0): float, function value at the root approximation.
"""
x_m= x_m
x_p= x_p
while True:
x_g = (x_p+ x_m) / 2.0
f_g = f(x_g)
if abs(f_g) <= eps_f and abs(x_p- x_g) <= eps_x:
return x_g, f_g
if f_g > 0:
x_p= x_g
else:
x_m= x_g
if __name__ == "__main__":
# Simple test: find sqrt(2) as root of f(x) = x^2 - 2
def f(x):
return x * x - 2.0
root, val = bis(f, 1.0, 2.0)
print(f"Root approximation: {root}")
print(f"f(root) = {val}")
print(f"x mismatch = {abs(root - 2**0.5)}")We say that algorithm has defined convergence if it is possible to express
Where is true root of the equation, is some constant, and is the order of convergence.
The best algorithms have quadratic convergence, i.e.
Generally the speed of the algorithm is related to its convergence order. However, other factors may affect the speed.
Need to provide a starting points and the derivative of the function.
Newton-Raphson method converges quadratically ().
Mathematical definition
The initial intent is to calculate it at very small .
Remember about round off errors
For computers with small enough .
Let’s be smarter. Recall Taylor series expansion
So we can see
Here computed approximation and algorithm error.
There is a range of optimal when both the round off and the algorithm errors are small.
Algorithm error for small
This is quite bad since error is proportional to .
So for small , the algorithm error dominates our approximation!
This is much better way (though it use an extra computation for a function)
Algorithm error
One option is to use root_scalar from scipy.optimize library