mirror of
https://github.com/TheAlgorithms/Python.git
synced 2026-03-13 09:50:19 +08:00
Delete arithmetic_analysis/ directory and relocate its contents (#10824)
* Remove eval from arithmetic_analysis/newton_raphson.py
* Relocate contents of arithmetic_analysis/
Delete the arithmetic_analysis/ directory and relocate its files because
the purpose of the directory was always ill-defined. "Arithmetic
analysis" isn't a field of math, and the directory's files contained
algorithms for linear algebra, numerical analysis, and physics.
Relocated the directory's linear algebra algorithms to linear_algebra/,
its numerical analysis algorithms to a new subdirectory called
maths/numerical_analysis/, and its single physics algorithm to physics/.
* updating DIRECTORY.md
---------
Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
55
maths/numerical_analysis/bisection.py
Normal file
55
maths/numerical_analysis/bisection.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
|
||||
def bisection(function: Callable[[float], float], a: float, b: float) -> float:
|
||||
"""
|
||||
finds where function becomes 0 in [a,b] using bolzano
|
||||
>>> bisection(lambda x: x ** 3 - 1, -5, 5)
|
||||
1.0000000149011612
|
||||
>>> bisection(lambda x: x ** 3 - 1, 2, 1000)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: could not find root in given interval.
|
||||
>>> bisection(lambda x: x ** 2 - 4 * x + 3, 0, 2)
|
||||
1.0
|
||||
>>> bisection(lambda x: x ** 2 - 4 * x + 3, 2, 4)
|
||||
3.0
|
||||
>>> bisection(lambda x: x ** 2 - 4 * x + 3, 4, 1000)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: could not find root in given interval.
|
||||
"""
|
||||
start: float = a
|
||||
end: float = b
|
||||
if function(a) == 0: # one of the a or b is a root for the function
|
||||
return a
|
||||
elif function(b) == 0:
|
||||
return b
|
||||
elif (
|
||||
function(a) * function(b) > 0
|
||||
): # if none of these are root and they are both positive or negative,
|
||||
# then this algorithm can't find the root
|
||||
raise ValueError("could not find root in given interval.")
|
||||
else:
|
||||
mid: float = start + (end - start) / 2.0
|
||||
while abs(start - mid) > 10**-7: # until precisely equals to 10^-7
|
||||
if function(mid) == 0:
|
||||
return mid
|
||||
elif function(mid) * function(start) < 0:
|
||||
end = mid
|
||||
else:
|
||||
start = mid
|
||||
mid = start + (end - start) / 2.0
|
||||
return mid
|
||||
|
||||
|
||||
def f(x: float) -> float:
|
||||
return x**3 - 2 * x - 5
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(bisection(f, 1, 1000))
|
||||
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
49
maths/numerical_analysis/intersection.py
Normal file
49
maths/numerical_analysis/intersection.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import math
|
||||
from collections.abc import Callable
|
||||
|
||||
|
||||
def intersection(function: Callable[[float], float], x0: float, x1: float) -> float:
|
||||
"""
|
||||
function is the f we want to find its root
|
||||
x0 and x1 are two random starting points
|
||||
>>> intersection(lambda x: x ** 3 - 1, -5, 5)
|
||||
0.9999999999954654
|
||||
>>> intersection(lambda x: x ** 3 - 1, 5, 5)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ZeroDivisionError: float division by zero, could not find root
|
||||
>>> intersection(lambda x: x ** 3 - 1, 100, 200)
|
||||
1.0000000000003888
|
||||
>>> intersection(lambda x: x ** 2 - 4 * x + 3, 0, 2)
|
||||
0.9999999998088019
|
||||
>>> intersection(lambda x: x ** 2 - 4 * x + 3, 2, 4)
|
||||
2.9999999998088023
|
||||
>>> intersection(lambda x: x ** 2 - 4 * x + 3, 4, 1000)
|
||||
3.0000000001786042
|
||||
>>> intersection(math.sin, -math.pi, math.pi)
|
||||
0.0
|
||||
>>> intersection(math.cos, -math.pi, math.pi)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ZeroDivisionError: float division by zero, could not find root
|
||||
"""
|
||||
x_n: float = x0
|
||||
x_n1: float = x1
|
||||
while True:
|
||||
if x_n == x_n1 or function(x_n1) == function(x_n):
|
||||
raise ZeroDivisionError("float division by zero, could not find root")
|
||||
x_n2: float = x_n1 - (
|
||||
function(x_n1) / ((function(x_n1) - function(x_n)) / (x_n1 - x_n))
|
||||
)
|
||||
if abs(x_n2 - x_n1) < 10**-5:
|
||||
return x_n2
|
||||
x_n = x_n1
|
||||
x_n1 = x_n2
|
||||
|
||||
|
||||
def f(x: float) -> float:
|
||||
return math.pow(x, 3) - (2 * x) - 5
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(intersection(f, 3, 3.5))
|
||||
57
maths/numerical_analysis/newton_forward_interpolation.py
Normal file
57
maths/numerical_analysis/newton_forward_interpolation.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# https://www.geeksforgeeks.org/newton-forward-backward-interpolation/
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
|
||||
# for calculating u value
|
||||
def ucal(u: float, p: int) -> float:
|
||||
"""
|
||||
>>> ucal(1, 2)
|
||||
0
|
||||
>>> ucal(1.1, 2)
|
||||
0.11000000000000011
|
||||
>>> ucal(1.2, 2)
|
||||
0.23999999999999994
|
||||
"""
|
||||
temp = u
|
||||
for i in range(1, p):
|
||||
temp = temp * (u - i)
|
||||
return temp
|
||||
|
||||
|
||||
def main() -> None:
|
||||
n = int(input("enter the numbers of values: "))
|
||||
y: list[list[float]] = []
|
||||
for _ in range(n):
|
||||
y.append([])
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
y[i].append(j)
|
||||
y[i][j] = 0
|
||||
|
||||
print("enter the values of parameters in a list: ")
|
||||
x = list(map(int, input().split()))
|
||||
|
||||
print("enter the values of corresponding parameters: ")
|
||||
for i in range(n):
|
||||
y[i][0] = float(input())
|
||||
|
||||
value = int(input("enter the value to interpolate: "))
|
||||
u = (value - x[0]) / (x[1] - x[0])
|
||||
|
||||
# for calculating forward difference table
|
||||
|
||||
for i in range(1, n):
|
||||
for j in range(n - i):
|
||||
y[j][i] = y[j + 1][i - 1] - y[j][i - 1]
|
||||
|
||||
summ = y[0][0]
|
||||
for i in range(1, n):
|
||||
summ += (ucal(u, i) * y[0][i]) / math.factorial(i)
|
||||
|
||||
print(f"the value at {value} is {summ}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
54
maths/numerical_analysis/newton_method.py
Normal file
54
maths/numerical_analysis/newton_method.py
Normal file
@@ -0,0 +1,54 @@
|
||||
"""Newton's Method."""
|
||||
|
||||
# Newton's Method - https://en.wikipedia.org/wiki/Newton%27s_method
|
||||
from collections.abc import Callable
|
||||
|
||||
RealFunc = Callable[[float], float] # type alias for a real -> real function
|
||||
|
||||
|
||||
# function is the f(x) and derivative is the f'(x)
|
||||
def newton(
|
||||
function: RealFunc,
|
||||
derivative: RealFunc,
|
||||
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: Could not find root
|
||||
"""
|
||||
prev_guess = float(starting_int)
|
||||
while True:
|
||||
try:
|
||||
next_guess = prev_guess - function(prev_guess) / derivative(prev_guess)
|
||||
except ZeroDivisionError:
|
||||
raise ZeroDivisionError("Could not find root") from None
|
||||
if abs(prev_guess - next_guess) < 10**-5:
|
||||
return next_guess
|
||||
prev_guess = next_guess
|
||||
|
||||
|
||||
def f(x: float) -> float:
|
||||
return (x**3) - (2 * x) - 5
|
||||
|
||||
|
||||
def f1(x: float) -> float:
|
||||
return 3 * (x**2) - 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(newton(f, f1, 3))
|
||||
45
maths/numerical_analysis/newton_raphson.py
Normal file
45
maths/numerical_analysis/newton_raphson.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# Implementing Newton Raphson method in Python
|
||||
# Author: Syed Haseeb Shah (github.com/QuantumNovice)
|
||||
# The Newton-Raphson method (also known as Newton's method) is a way to
|
||||
# quickly find a good approximation for the root of a real-valued function
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from sympy import diff, lambdify, symbols
|
||||
|
||||
|
||||
def newton_raphson(func: str, a: float | Decimal, precision: float = 1e-10) -> float:
|
||||
"""Finds root from the point 'a' onwards by Newton-Raphson method
|
||||
>>> newton_raphson("sin(x)", 2)
|
||||
3.1415926536808043
|
||||
>>> newton_raphson("x**2 - 5*x + 2", 0.4)
|
||||
0.4384471871911695
|
||||
>>> newton_raphson("x**2 - 5", 0.1)
|
||||
2.23606797749979
|
||||
>>> newton_raphson("log(x) - 1", 2)
|
||||
2.718281828458938
|
||||
"""
|
||||
x = symbols("x")
|
||||
f = lambdify(x, func, "math")
|
||||
f_derivative = lambdify(x, diff(func), "math")
|
||||
x_curr = a
|
||||
while True:
|
||||
x_curr = Decimal(x_curr) - Decimal(f(x_curr)) / Decimal(f_derivative(x_curr))
|
||||
if abs(f(x_curr)) < precision:
|
||||
return float(x_curr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
|
||||
# Find value of pi
|
||||
print(f"The root of sin(x) = 0 is {newton_raphson('sin(x)', 2)}")
|
||||
# Find root of polynomial
|
||||
print(f"The root of x**2 - 5*x + 2 = 0 is {newton_raphson('x**2 - 5*x + 2', 0.4)}")
|
||||
# Find value of e
|
||||
print(f"The root of log(x) - 1 = 0 is {newton_raphson('log(x) - 1', 2)}")
|
||||
# Find root of exponential function
|
||||
print(f"The root of exp(x) - 1 = 0 is {newton_raphson('exp(x) - 1', 0)}")
|
||||
83
maths/numerical_analysis/newton_raphson_new.py
Normal file
83
maths/numerical_analysis/newton_raphson_new.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# Implementing Newton Raphson method in Python
|
||||
# Author: Saksham Gupta
|
||||
#
|
||||
# The Newton-Raphson method (also known as Newton's method) is a way to
|
||||
# quickly find a good approximation for the root of a functreal-valued ion
|
||||
# The method can also be extended to complex functions
|
||||
#
|
||||
# Newton's Method - https://en.wikipedia.org/wiki/Newton's_method
|
||||
|
||||
from sympy import diff, lambdify, symbols
|
||||
from sympy.functions import * # noqa: F403
|
||||
|
||||
|
||||
def newton_raphson(
|
||||
function: str,
|
||||
starting_point: complex,
|
||||
variable: str = "x",
|
||||
precision: float = 10**-10,
|
||||
multiplicity: int = 1,
|
||||
) -> complex:
|
||||
"""Finds root from the 'starting_point' onwards by Newton-Raphson method
|
||||
Refer to https://docs.sympy.org/latest/modules/functions/index.html
|
||||
for usable mathematical functions
|
||||
|
||||
>>> newton_raphson("sin(x)", 2)
|
||||
3.141592653589793
|
||||
>>> newton_raphson("x**4 -5", 0.4 + 5j)
|
||||
(-7.52316384526264e-37+1.4953487812212207j)
|
||||
>>> newton_raphson('log(y) - 1', 2, variable='y')
|
||||
2.7182818284590455
|
||||
>>> newton_raphson('exp(x) - 1', 10, precision=0.005)
|
||||
1.2186556186174883e-10
|
||||
>>> newton_raphson('cos(x)', 0)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ZeroDivisionError: Could not find root
|
||||
"""
|
||||
|
||||
x = symbols(variable)
|
||||
func = lambdify(x, function)
|
||||
diff_function = lambdify(x, diff(function, x))
|
||||
|
||||
prev_guess = starting_point
|
||||
|
||||
while True:
|
||||
if diff_function(prev_guess) != 0:
|
||||
next_guess = prev_guess - multiplicity * func(prev_guess) / diff_function(
|
||||
prev_guess
|
||||
)
|
||||
else:
|
||||
raise ZeroDivisionError("Could not find root") from None
|
||||
|
||||
# Precision is checked by comparing the difference of consecutive guesses
|
||||
if abs(next_guess - prev_guess) < precision:
|
||||
return next_guess
|
||||
|
||||
prev_guess = next_guess
|
||||
|
||||
|
||||
# Let's Execute
|
||||
if __name__ == "__main__":
|
||||
# Find root of trigonometric function
|
||||
# Find value of pi
|
||||
print(f"The root of sin(x) = 0 is {newton_raphson('sin(x)', 2)}")
|
||||
|
||||
# Find root of polynomial
|
||||
# Find fourth Root of 5
|
||||
print(f"The root of x**4 - 5 = 0 is {newton_raphson('x**4 -5', 0.4 +5j)}")
|
||||
|
||||
# Find value of e
|
||||
print(
|
||||
"The root of log(y) - 1 = 0 is ",
|
||||
f"{newton_raphson('log(y) - 1', 2, variable='y')}",
|
||||
)
|
||||
|
||||
# Exponential Roots
|
||||
print(
|
||||
"The root of exp(x) - 1 = 0 is",
|
||||
f"{newton_raphson('exp(x) - 1', 10, precision=0.005)}",
|
||||
)
|
||||
|
||||
# Find root of cos(x)
|
||||
print(f"The root of cos(x) = 0 is {newton_raphson('cos(x)', 0)}")
|
||||
29
maths/numerical_analysis/secant_method.py
Normal file
29
maths/numerical_analysis/secant_method.py
Normal file
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
Implementing Secant method in Python
|
||||
Author: dimgrichr
|
||||
"""
|
||||
from math import exp
|
||||
|
||||
|
||||
def f(x: float) -> float:
|
||||
"""
|
||||
>>> f(5)
|
||||
39.98652410600183
|
||||
"""
|
||||
return 8 * x - 2 * exp(-x)
|
||||
|
||||
|
||||
def secant_method(lower_bound: float, upper_bound: float, repeats: int) -> float:
|
||||
"""
|
||||
>>> secant_method(1, 3, 2)
|
||||
0.2139409276214589
|
||||
"""
|
||||
x0 = lower_bound
|
||||
x1 = upper_bound
|
||||
for _ in range(repeats):
|
||||
x0, x1 = x1, x1 - (f(x1) * (x1 - x0)) / (f(x1) - f(x0))
|
||||
return x1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f"Example: {secant_method(1, 3, 2)}")
|
||||
Reference in New Issue
Block a user