Created
March 9, 2015 10:43
-
-
Save adhikasp/d01a4c3de39d7549a0a3 to your computer and use it in GitHub Desktop.
Teknik Komputasi JTETI 2015, Source code pencarian akar polinomial dengan metode numeris
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# Bahasa python | |
# print('========================================================') | |
# print('Metode pencarian akar polinomial dengan metode numeris') | |
# print('Adhika Setya Pramudita') | |
# print('NIM 14/365240/TK/42058') | |
# print('\n\n') | |
import math | |
# Because floating point is hard... | |
# This number used for deciding if some variable is (aproaching) zero | |
FLOAT_ZERO_TOLERANCE = 1e-4 | |
# Degree of outputed decimal point | |
DECIMAL_ACC = 8 | |
def bisectionMethod(funct, lowerX, upperX, intendedError = 0.1, verbose = False): | |
""" | |
Argument: | |
Function funct -> math function that we try to evaluate | |
float lowerX -> lower prediction | |
float lowerY -> upper prediction | |
float intendedError -> Acceptable relative error, in **percent** | |
bool verbose -> if true, output some calculated variable while iterating. | |
Usefull for debugging calculation. | |
Return: | |
float middleX -> predicted root of input math funtion | |
""" | |
if verbose: | |
print('Bisection Method') | |
debugIterator = 1 | |
upperFunct = funct(upperX) | |
lowerFunct = funct(lowerX) | |
oldX = 0 | |
error = 100 | |
# Check if initial prediction is on the SAME SIDE relative to the root. | |
# If true, then the initial value is invalid, and lets bail out. | |
if upperFunct * lowerFunct > 0: | |
return False | |
while error > intendedError: | |
middleX = (upperX + lowerX) / 2 | |
middleFunct = funct(middleX) | |
if abs(middleFunct) < FLOAT_ZERO_TOLERANCE: | |
return middleX | |
elif middleFunct < 0: | |
lowerX = middleX | |
lowerFunct = middleFunct | |
elif middleFunct > 0: | |
upperX = middleX | |
upperFunct = middleFunct | |
error = math.fabs(((oldX - middleX )/middleX)) * 100 | |
oldX = middleX | |
if verbose: | |
print("Iterasi {:<3d} :: X = {:+.8f} :: error = {:.2f}".format(debugIterator, middleX, error)) | |
debugIterator+=1 | |
return middleX | |
def secantIteration(func, firstX, secondX, intendedError=0.1, verbose=False): | |
if verbose: | |
print('Secant Method') | |
debugIterator = 1 | |
error = 100 | |
roundingError = int(abs(math.log10(intendedError))) | |
while error > intendedError: | |
upperFormula = func(firstX) * (firstX - secondX) | |
bottomFormula = func(firstX) - func(secondX) | |
nextX = firstX - ( upperFormula / bottomFormula ) | |
error = math.fabs((secondX - nextX )/nextX) * 100 | |
firstX, secondX = secondX, nextX | |
if verbose: | |
print ("Iterasi {2:<3d} :: X = {0:+.8f} :: error = {1}".format(nextX, round(error, roundingError), debugIterator)) | |
debugIterator += 1 | |
return nextX | |
def modifiedSecant(func, firstX, delta, intendedError=0.1, verbose=False): | |
if verbose: | |
print('Modified Secant Method') | |
debugIterator = 1 | |
error = 100 | |
while error > intendedError: | |
upperFormula = delta * firstX * func(firstX) | |
bottomFormula = func(firstX * delta + firstX) - func(firstX) | |
nextX = firstX - ( upperFormula / bottomFormula ) | |
error = math.fabs((firstX - nextX )/nextX) * 100 | |
firstX = nextX | |
if verbose: | |
print ("Iterasi {2:<3d} :: X = {0:+.8f} :: error = {1}".format(nextX, error, debugIterator)) | |
debugIterator += 1 | |
return nextX | |
def newtonRaphson(func, derv, x, intendedError=0.1, verbose=False): | |
if verbose: | |
print('Newton Raphson Method') | |
debugIterator = 1 | |
error = 100 | |
oldX = x | |
while error > intendedError: | |
nextX = oldX - func(oldX)/derv(oldX); | |
error = math.fabs((oldX - nextX)/nextX) * 100 | |
oldX = nextX | |
if verbose: | |
print ("Iterasi {0:<3d} :: X = {1} :: error = {2}".format(debugIterator, nextX, error)) | |
debugIterator += 1 | |
return nextX; | |
def fixedPoint(func_G, firstX, intendedError = 0.1, verbose = False): | |
estimatedRoot = firstX | |
error = 100 | |
if verbose: | |
print("Fixed Point Method") | |
debugIterator = 1 | |
while error > intendedError: | |
oldRoot = estimatedRoot | |
estimatedRoot = func_G(oldRoot) | |
error = math.fabs((estimatedRoot - oldRoot) / estimatedRoot) * 100 | |
if verbose: | |
print("Iterasi {:<3d} :: X = {:+.6f} :: error = {:.2f}".format(debugIterator, estimatedRoot, error)) | |
debugIterator += 1 | |
return estimatedRoot | |
assert((abs(bisectionMethod(lambda x: x**2 - 25, 3, 9, 0.001) - 5) < FLOAT_ZERO_TOLERANCE) and "Something wrong with bisectionMethod()") | |
if __name__ == "__main__": | |
print('========================================================') | |
print('Metode pencarian akar polinomial dengan metode numeris') | |
print('Adhika Setya Pramudita') | |
print('NIM 14/365240/TK/42058') | |
print('\n\n') | |
RELATIVE_ERROR = 1e-2 | |
VERBOSE_MODE = True | |
print('Soal Pertama') | |
print('Estimasi akar dari fungsi f(x) = -0.6*x**2 + 2.4 * x + 5.5 :\n') | |
fungsi_pertama = lambda x: -0.6*x**2 + 2.4 * x + 5.5 | |
akar = bisectionMethod(fungsi_pertama, 10, 5, RELATIVE_ERROR, VERBOSE_MODE) | |
print('Estimasi : {}'.format(akar)) | |
print('\n\nSoal Kedua') | |
print('Estimasi akar dari fungsi f(x) = 2*x**3 - 11.7*x**2 + 17.7*x - 5 :\n') | |
fungsi_kedua = lambda x: 2*x**3 - 11.7*x**2 + 17.7*x - 5 | |
turunan_kedua = lambda x: 6*x**2 - 22.7*x + 17.7 | |
fungsi_kedua_G = lambda x: (-2*x**3 + 11.7*x**2 + 5) / 17.7 | |
akar = fixedPoint(fungsi_kedua_G, 3, RELATIVE_ERROR, VERBOSE_MODE) | |
print('Estimasi : {}'.format(akar)) # 3.563041530161226 | |
akar = newtonRaphson(fungsi_kedua, turunan_kedua, 3, RELATIVE_ERROR, VERBOSE_MODE) | |
print('Estimasi : {}'.format(akar)) # 3.5631962898474554 | |
akar = secantIteration(fungsi_kedua, 4, 3, RELATIVE_ERROR, VERBOSE_MODE) | |
print('Estimasi : {}'.format(akar)) # 3.5631608179476646 | |
akar = modifiedSecant(fungsi_kedua, 3, 0.01, RELATIVE_ERROR, VERBOSE_MODE) | |
print('Estimasi : {}'.format(akar)) # 3.5631624723484667 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment