Skip to content

Commit d35e595

Browse files
committed
Inital commit. Package has been published to PyPI!
1 parent 0640902 commit d35e595

File tree

13 files changed

+321
-0
lines changed

13 files changed

+321
-0
lines changed

.DS_Store

6 KB
Binary file not shown.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from bisection import bisection
2+
3+
exampleFuncs = {
4+
'linFuncString': '2*x-19',
5+
'polyFunc': 'x**2+x-5',
6+
'trigFuncOne': 'math.sin(1/x)',
7+
'trigFuncTwo': 'math.sin(x)/x'
8+
}
3.79 KB
Binary file not shown.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Calculus Bisection Class Project
2+
# Author: Nicholas Assaderaghi (FlyN Nick)
3+
# Translated from TypeScript to Python (see https://github.com/FlyN-Nick/Bisection-Method-TypeScript).
4+
5+
import math
6+
#import sys
7+
8+
def convert(f, x: float) -> float:
9+
"""Returns the value of an expression given x."""
10+
if type(f) is str:
11+
return eval(f)
12+
return f(x)
13+
14+
def bisection(f, min: float, max: float, maxIter=100, annoyingPrints=False):
15+
"""Bisection function: finds the root of a function within given range.
16+
17+
Things that may cause this to be unsuccessfull/error:
18+
#1: Root is not within given range.
19+
#2: Function changes signs more than once within given range.
20+
#3: The given minimum is greater than the given maximum.
21+
#4: There are x within given range where f(x) is undefined.
22+
23+
Parameters
24+
----------
25+
f : str or function
26+
Function that is being evaluated.
27+
min : float
28+
The given lower bound of the possible range of the root
29+
max : float
30+
The given upper bound of the possible range of the root
31+
maxIter : int, optional
32+
The maximum number of iterations (default 1000)
33+
annoyingPrints : bool, optional
34+
Enables an annoying print statement every iteration (default False)
35+
"""
36+
37+
print('---------------------------------------------------------------');
38+
39+
if min > max:
40+
print('You seem to have mixed the min and max...')
41+
return 'ERROR'
42+
elif min is max and convert(f, min) == 0:
43+
print('Wow, the given min and max were the same and were the root. Kinda seems like this was on purpose...')
44+
return min
45+
elif min is max:
46+
print('Wow, the given min and max were the same but were not the root. Kinda seems like this was on purpose...')
47+
return 'ERROR'
48+
elif convert(f, min) == 0:
49+
print('Wow, the lower bound of the given range was the root. Kinda seems like this was on purpose...')
50+
return min
51+
elif convert(f, max) == 0:
52+
print('Wow, the upper bound of the given range was the root. Kinda seems like this was on purpose...')
53+
return max
54+
55+
posSlope = True
56+
if convert(f, min) > convert(f, (min+max/2)):
57+
posSlope = False
58+
59+
iter = 0
60+
while iter != maxIter:
61+
iter += 1
62+
guess = (min+max)/2
63+
64+
if (convert(f, guess) < 0 and posSlope) or (convert(f, guess) > 0 and not posSlope):
65+
if guess == min:
66+
print(f'Stopped at iteration #{iter}.')
67+
print(f'Root not found.\nRange: ({min}, {max}).')
68+
return [min, max]
69+
min = guess
70+
elif (convert(f, guess) > 0 and posSlope) or (convert(f, guess) < 0 and not posSlope):
71+
if guess == max:
72+
print(f'Stopped at iteration #{iter}.')
73+
print(f'Root not found.\nRange: ({min}, {max}).')
74+
return [min, max]
75+
max = guess
76+
else:
77+
print(f'Root: {guess}.\nIterations it took: {iter}.')
78+
return guess
79+
if annoyingPrints:
80+
print(f'Iteration #{iter}:\n\tCurrent range: ({min}, {max})')
81+
82+
print(f'Root not found (maximum iterations reached).\nRange: ({min}, {max}).')
83+
84+
print(f'Remember, this algorithm will only work if:\n\t#1: The root is within the range.\n\t#2: The function changes sign once within the interval.')
85+
86+
return [min, max]
87+
88+
def testBisectionFunction():
89+
"""Just testing if everything generally works. This is not an in-depth test (does not test all error scenarios)."""
90+
print('TESTING BISECTION FUNCTION!\n')
91+
92+
def linFunc(x: float) -> float:
93+
return 2*x-19
94+
95+
linFuncString = '2*x-19'
96+
polyFunc = 'x**2+x-5'
97+
trigFuncOne = 'math.sin(1/x)'
98+
trigFuncTwo = 'math.sin(x)/x'
99+
100+
returnedVals = [
101+
bisection(linFunc, 9.5, 9.5), # root is both given min and max
102+
bisection(linFunc, 5, 5), # given min and max are the same, but not the root
103+
bisection(linFunc, 9.5, 10), # root is the given min
104+
bisection(linFunc, 9, 9.5), # root is the given max
105+
bisection(linFunc, -100, 0), # root not within range
106+
bisection(linFunc, 100, -100), # upper and lower switched
107+
bisection(linFuncString, -100, 100),
108+
bisection(polyFunc, 0, 21),
109+
bisection(trigFuncOne, 0.212, 0.637, 100000),
110+
bisection(trigFuncTwo, 0.1, 4.25, 1000)
111+
]
112+
113+
print('---------------------------------------------------------------')
114+
print(f'\nReturned values from bisection function:\n[');
115+
116+
length = len(returnedVals)
117+
i = 0
118+
#print(returnedVals)
119+
for returnedVal in returnedVals:
120+
i += 1
121+
if i != length:
122+
print(f'\t{returnedVal},')
123+
else:
124+
print(f'\t{returnedVal}\n]')
125+
126+
if __name__ == '__main__':
127+
testBisectionFunction()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Metadata-Version: 2.1
2+
Name: bisection-method-flyn-nick
3+
Version: 1.0.0
4+
Summary: An implementation of the bisection method in python.
5+
Home-page: https://github.com/FlyN-Nick/Bisection-Method-Python
6+
Author: Nicholas Assaderaghi
7+
Author-email: nickassader@gmail.com
8+
License: UNKNOWN
9+
Description: # Bisection-Method-Python
10+
A quick implementation of the Bisection Method in Python.
11+
12+
Keywords: bisection method
13+
Platform: UNKNOWN
14+
Classifier: Programming Language :: Python :: 3
15+
Classifier: License :: OSI Approved :: MIT License
16+
Classifier: Operating System :: OS Independent
17+
Requires-Python: >=3.6
18+
Description-Content-Type: text/markdown
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
README.md
2+
setup.py
3+
Bisection-Method-Python/__init__.py
4+
Bisection-Method-Python/bisection.py
5+
bisection_method_flyn_nick.egg-info/PKG-INFO
6+
bisection_method_flyn_nick.egg-info/SOURCES.txt
7+
bisection_method_flyn_nick.egg-info/dependency_links.txt
8+
bisection_method_flyn_nick.egg-info/top_level.txt
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Bisection-Method-Python
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from bisection import bisection
2+
3+
exampleFuncs = {
4+
'linFuncString': '2*x-19',
5+
'polyFunc': 'x**2+x-5',
6+
'trigFuncOne': 'math.sin(1/x)',
7+
'trigFuncTwo': 'math.sin(x)/x'
8+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Calculus Bisection Class Project
2+
# Author: Nicholas Assaderaghi (FlyN Nick)
3+
# Translated from TypeScript to Python (see https://github.com/FlyN-Nick/Bisection-Method-TypeScript).
4+
5+
import math
6+
#import sys
7+
8+
def convert(f, x: float) -> float:
9+
"""Returns the value of an expression given x."""
10+
if type(f) is str:
11+
return eval(f)
12+
return f(x)
13+
14+
def bisection(f, min: float, max: float, maxIter=100, annoyingPrints=False):
15+
"""Bisection function: finds the root of a function within given range.
16+
17+
Things that may cause this to be unsuccessfull/error:
18+
#1: Root is not within given range.
19+
#2: Function changes signs more than once within given range.
20+
#3: The given minimum is greater than the given maximum.
21+
#4: There are x within given range where f(x) is undefined.
22+
23+
Parameters
24+
----------
25+
f : str or function
26+
Function that is being evaluated.
27+
min : float
28+
The given lower bound of the possible range of the root
29+
max : float
30+
The given upper bound of the possible range of the root
31+
maxIter : int, optional
32+
The maximum number of iterations (default 1000)
33+
annoyingPrints : bool, optional
34+
Enables an annoying print statement every iteration (default False)
35+
"""
36+
37+
print('---------------------------------------------------------------');
38+
39+
if min > max:
40+
print('You seem to have mixed the min and max...')
41+
return 'ERROR'
42+
elif min is max and convert(f, min) == 0:
43+
print('Wow, the given min and max were the same and were the root. Kinda seems like this was on purpose...')
44+
return min
45+
elif min is max:
46+
print('Wow, the given min and max were the same but were not the root. Kinda seems like this was on purpose...')
47+
return 'ERROR'
48+
elif convert(f, min) == 0:
49+
print('Wow, the lower bound of the given range was the root. Kinda seems like this was on purpose...')
50+
return min
51+
elif convert(f, max) == 0:
52+
print('Wow, the upper bound of the given range was the root. Kinda seems like this was on purpose...')
53+
return max
54+
55+
posSlope = True
56+
if convert(f, min) > convert(f, (min+max/2)):
57+
posSlope = False
58+
59+
iter = 0
60+
while iter != maxIter:
61+
iter += 1
62+
guess = (min+max)/2
63+
64+
if (convert(f, guess) < 0 and posSlope) or (convert(f, guess) > 0 and not posSlope):
65+
if guess == min:
66+
print(f'Stopped at iteration #{iter}.')
67+
print(f'Root not found.\nRange: ({min}, {max}).')
68+
return [min, max]
69+
min = guess
70+
elif (convert(f, guess) > 0 and posSlope) or (convert(f, guess) < 0 and not posSlope):
71+
if guess == max:
72+
print(f'Stopped at iteration #{iter}.')
73+
print(f'Root not found.\nRange: ({min}, {max}).')
74+
return [min, max]
75+
max = guess
76+
else:
77+
print(f'Root: {guess}.\nIterations it took: {iter}.')
78+
return guess
79+
if annoyingPrints:
80+
print(f'Iteration #{iter}:\n\tCurrent range: ({min}, {max})')
81+
82+
print(f'Root not found (maximum iterations reached).\nRange: ({min}, {max}).')
83+
84+
print(f'Remember, this algorithm will only work if:\n\t#1: The root is within the range.\n\t#2: The function changes sign once within the interval.')
85+
86+
return [min, max]
87+
88+
def testBisectionFunction():
89+
"""Just testing if everything generally works. This is not an in-depth test (does not test all error scenarios)."""
90+
print('TESTING BISECTION FUNCTION!\n')
91+
92+
def linFunc(x: float) -> float:
93+
return 2*x-19
94+
95+
linFuncString = '2*x-19'
96+
polyFunc = 'x**2+x-5'
97+
trigFuncOne = 'math.sin(1/x)'
98+
trigFuncTwo = 'math.sin(x)/x'
99+
100+
returnedVals = [
101+
bisection(linFunc, 9.5, 9.5), # root is both given min and max
102+
bisection(linFunc, 5, 5), # given min and max are the same, but not the root
103+
bisection(linFunc, 9.5, 10), # root is the given min
104+
bisection(linFunc, 9, 9.5), # root is the given max
105+
bisection(linFunc, -100, 0), # root not within range
106+
bisection(linFunc, 100, -100), # upper and lower switched
107+
bisection(linFuncString, -100, 100),
108+
bisection(polyFunc, 0, 21),
109+
bisection(trigFuncOne, 0.212, 0.637, 100000),
110+
bisection(trigFuncTwo, 0.1, 4.25, 1000)
111+
]
112+
113+
print('---------------------------------------------------------------')
114+
print(f'\nReturned values from bisection function:\n[');
115+
116+
length = len(returnedVals)
117+
i = 0
118+
#print(returnedVals)
119+
for returnedVal in returnedVals:
120+
i += 1
121+
if i != length:
122+
print(f'\t{returnedVal},')
123+
else:
124+
print(f'\t{returnedVal}\n]')
125+
126+
if __name__ == '__main__':
127+
testBisectionFunction()

0 commit comments

Comments
 (0)