Skip to content

Instantly share code, notes, and snippets.

@adhikasp
Created March 9, 2015 10:43
Show Gist options
  • Save adhikasp/d01a4c3de39d7549a0a3 to your computer and use it in GitHub Desktop.
Save adhikasp/d01a4c3de39d7549a0a3 to your computer and use it in GitHub Desktop.
Teknik Komputasi JTETI 2015, Source code pencarian akar polinomial dengan metode numeris
#!/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