-
-
Notifications
You must be signed in to change notification settings - Fork 46.6k
added type hints and doctests to arithmetic_analysis/newton_method.py #2259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
f26b8b2
4ad625d
8e20e61
d55491a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,23 +1,50 @@ | ||||||||||||||||||
"""Newton's Method.""" | ||||||||||||||||||
|
||||||||||||||||||
# Newton's Method - https://en.wikipedia.org/wiki/Newton%27s_method | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
# function is the f(x) and function1 is the f'(x) | ||||||||||||||||||
def newton(function, function1, startingInt): | ||||||||||||||||||
x_n = startingInt | ||||||||||||||||||
from typing import Callable | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
# function is the f(x) and derivative is the f'(x) | ||||||||||||||||||
def newton( | ||||||||||||||||||
function: Callable[[float], float], | ||||||||||||||||||
derivative: Callable[[float], float], | ||||||||||||||||||
starting_int: int, | ||||||||||||||||||
) -> float: | ||||||||||||||||||
""" | ||||||||||||||||||
>>> 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): | ||||||||||||||||||
... | ||||||||||||||||||
ZeroDivisionError: float division by zero, could not find root | ||||||||||||||||||
""" | ||||||||||||||||||
prev_guess: float = starting_int | ||||||||||||||||||
while True: | ||||||||||||||||||
x_n1 = x_n - function(x_n) / function1(x_n) | ||||||||||||||||||
if abs(x_n - x_n1) < 10 ** -5: | ||||||||||||||||||
return x_n1 | ||||||||||||||||||
x_n = x_n1 | ||||||||||||||||||
if derivative(prev_guess) == 0: | ||||||||||||||||||
raise ZeroDivisionError("float division by zero, could not find root") | ||||||||||||||||||
|
||||||||||||||||||
next_guess: float = prev_guess - function(prev_guess) / derivative(prev_guess) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Avoid calculating the derivative twice. The error type already says that we have a division by zero -- we do not need to repeat. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense, got it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @spamegg1, from OSSU here. I was just going through this issue and looking at the changes made and this will create a problem where if there is a >>> try:
... a = 1/0
... except ZeroDivisionError:
... raise ZeroDivisionError("Not possible")
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
ZeroDivisionError: Not possible Why? the >>> try:
... a = 1/0
... except ZeroDivisionError:
... raise ZeroDivisionError("Not possible") from None
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
ZeroDivisionError: Not possible You can also use |
||||||||||||||||||
if abs(prev_guess - next_guess) < 10 ** -5: | ||||||||||||||||||
return next_guess | ||||||||||||||||||
prev_guess = next_guess | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
def f(x): | ||||||||||||||||||
def f(x: float) -> float: | ||||||||||||||||||
return (x ** 3) - (2 * x) - 5 | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
def f1(x): | ||||||||||||||||||
def f1(x: float) -> float: | ||||||||||||||||||
return 3 * (x ** 2) - 2 | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to defined a type for
Callable[[float], float]
and then use that type to simplify the call parameters?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... I think there is. I could try defining a type hint alias as described here:
https://docs.python.org/3/library/typing.html#type-aliases
Let me try and see if it passes mypy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you know? It does work!