2019-07-01 08:10:18 +00:00
|
|
|
"""Newton's Method."""
|
|
|
|
|
2018-11-05 17:19:08 +00:00
|
|
|
# Newton's Method - https://en.wikipedia.org/wiki/Newton%27s_method
|
2022-07-11 08:19:52 +00:00
|
|
|
from collections.abc import Callable
|
2020-08-01 13:17:46 +00:00
|
|
|
|
|
|
|
RealFunc = Callable[[float], float] # type alias for a real -> real function
|
|
|
|
|
|
|
|
|
|
|
|
# function is the f(x) and derivative is the f'(x)
|
2020-09-10 08:31:26 +00:00
|
|
|
def newton(
|
|
|
|
function: RealFunc,
|
|
|
|
derivative: RealFunc,
|
|
|
|
starting_int: int,
|
|
|
|
) -> float:
|
2020-08-01 13:17:46 +00:00
|
|
|
"""
|
|
|
|
>>> newton(lambda x: x ** 3 - 2 * x - 5, lambda x: 3 * x ** 2 - 2, 3)
|
|
|
|
2.0945514815423474
|
|
|
|
>>> newton(lambda x: x ** 3 - 1, lambda x: 3 * x ** 2, -2)
|
|
|
|
1.0
|
|
|
|
>>> newton(lambda x: x ** 3 - 1, lambda x: 3 * x ** 2, -4)
|
|
|
|
1.0000000000000102
|
|
|
|
>>> import math
|
|
|
|
>>> newton(math.sin, math.cos, 1)
|
|
|
|
0.0
|
|
|
|
>>> newton(math.sin, math.cos, 2)
|
|
|
|
3.141592653589793
|
|
|
|
>>> newton(math.cos, lambda x: -math.sin(x), 2)
|
|
|
|
1.5707963267948966
|
|
|
|
>>> newton(math.cos, lambda x: -math.sin(x), 0)
|
|
|
|
Traceback (most recent call last):
|
2022-10-27 17:42:30 +00:00
|
|
|
...
|
2020-08-01 13:17:46 +00:00
|
|
|
ZeroDivisionError: Could not find root
|
|
|
|
"""
|
2020-08-01 20:11:39 +00:00
|
|
|
prev_guess = float(starting_int)
|
2019-07-01 08:10:18 +00:00
|
|
|
while True:
|
2020-08-01 13:17:46 +00:00
|
|
|
try:
|
|
|
|
next_guess = prev_guess - function(prev_guess) / derivative(prev_guess)
|
|
|
|
except ZeroDivisionError:
|
2020-09-27 13:05:09 +00:00
|
|
|
raise ZeroDivisionError("Could not find root") from None
|
2022-01-30 19:29:54 +00:00
|
|
|
if abs(prev_guess - next_guess) < 10**-5:
|
2020-08-01 13:17:46 +00:00
|
|
|
return next_guess
|
|
|
|
prev_guess = next_guess
|
2019-07-01 08:10:18 +00:00
|
|
|
|
|
|
|
|
2020-08-01 13:17:46 +00:00
|
|
|
def f(x: float) -> float:
|
2022-01-30 19:29:54 +00:00
|
|
|
return (x**3) - (2 * x) - 5
|
2019-07-01 08:10:18 +00:00
|
|
|
|
2018-10-19 12:48:28 +00:00
|
|
|
|
2020-08-01 13:17:46 +00:00
|
|
|
def f1(x: float) -> float:
|
2022-01-30 19:29:54 +00:00
|
|
|
return 3 * (x**2) - 2
|
2019-07-01 08:10:18 +00:00
|
|
|
|
2018-10-19 12:48:28 +00:00
|
|
|
|
2018-11-05 17:19:08 +00:00
|
|
|
if __name__ == "__main__":
|
2019-07-01 08:10:18 +00:00
|
|
|
print(newton(f, f1, 3))
|