def bisection(a, b, fn, e): """ S vyuzitim metody Bisekcie vypocita koren funkcie fn na intervale <a,b>. """ assert a < b, 'Cislo b musi byt vacsie ako cislo a' assert e > 0, 'Presnost e musi byt vacsia ako nula' f = lambda x: eval_expr(fn, x=x) while True: # stred intervalu <a,b> x = 0.5 * (a + b) logger.info('a = {0}, b = {1}, x = {2}'.format(a, b, x)) # skonci ak je stred intervalu # korenom funkcie inak uprav interval if f(x) == 0: return x elif f(a) * f(x) < 0: b = x else: a = x # skonci pri dosiahnuti presnosti if b - a <= e: return x
def gaussseidel(a, b, x, e): """ S vyuzitim Gauss Seidelovej metody vypocita sustavu linearnych rovnic. Matica a reprezentuje lavu stranu sustavy, matica b vektor pravej strany a matica x reprezentuje vektor aproximacie. Priklad: Nevyhovujuca: a = Matrix(( [1,1,-3], [2,5,1], [4,-1,2], )) b = [-4,5,-12] Vyhovujuca: a = Matrix(( [11,2,1], [1,10,2], [2,3,-8], )) b = [15,16,1] """ assert a.rows == len(b) == len(x), \ 'Rozmery matice "a" a pocet prvkov vo vektoroch "b" a "x" ' \ 'musi byt rovnaky' assert e > 0, 'Presnost e musi byt vacsia ako nula' assert check_norms(a), 'Matica nesplna konvergencne kriterium' # novy vektor aproximacie x1 = list(x) while True: for i in range(a.rows): sum_a = sum_b = 0 for j in range(i): sum_a += a[i, j] * x1[j] for j in range(i + 1, a.rows): sum_b += a[i, j] * x[j] # vypocet dalsej aproximacie x1[i] = (1 / a[i, i]) * (b[i] - sum_a - sum_b) # vypocet rozdielu prvej a druhej aproximacie (norma) error = norm_error(x1, x) logger.info('x1 = {0}\nx = {1}\nerror = {2}\n'.format( list_as_float(x1), list_as_float(x), float(error))) # skonci pri dosiahnuti presnosti if error <= e: return list_as_float(x1) x = list(x1)
def leastsquares(x, fx): """ S vyuzitim metody najmensich stvorcov urci priamku blizko predpisanym hodnotam. """ # pocet x n = len(x) assert n == len(fx), 'Dlzka listov x a fx musi byt rovnaka' # suma 1 * n sum_1 = n # suma vsetkych x sum_x = sum(x) # suma vsetkych mocnin x sum_x2 = sum([i**2 for i in x]) # suma vsetkych fx sum_fx = sum(fx) # suma vsetkych x * fx sum_x_fx = sum(xi * fxi for xi, fxi in zip(x, fx)) logger.info( 'sum_1 = {0}, sum_x = {1}, sum_x2 = {2}, sum_fx = {3}, sum_x_fx = {4}\n' .format(sum_1, sum_x, sum_x2, sum_fx, sum_x_fx)) # lava strana sustavy a = Matrix(( [sum_1, sum_x], [sum_x, sum_x2], )) # prava strana sustavy b = [sum_fx, sum_x_fx] # aproximacia riesenia pre jacobiho metodu x = [0, 0] # jacobiho metodou vypocita sustavu c1, c2 = jacobi(a, b, x, e=0.01) return '{0} + {1}x'.format(c1, c2)
def trapezoid(a, b, m, fn, e): """ Na intervale <a,b>, ktory sa rozdeli na m lichobeznikov, vypocita aproximaciu urciteho integralu funkcie fn. """ assert a < b, 'Cislo b musi byt vacsie ako cislo a' assert e > 0, 'Presnost e musi byt vacsia ako nula' f = lambda x: eval_expr(fn, x=x) I = [] J1 = 0 J2 = 0 k = 0 # rozdelenie intervalu na m rovnako dlhych dielov h = (b - a) / m for i in range(m): J1 += f(a + (h * i)) J2 += f(a + h * (i + 1)) I.append((h / 2) * (J1 + J2)) while True: J1 = 0 J2 = 0 m *= 2 # skratenie intervalu na polovicu h /= 2 for i in range(m): J1 += f(a + (h * i)) J2 += f(a + h * (i + 1)) I.append((h / 2) * (J1 + J2)) logger.info('m = {0}, h = {1}, Abs(I[k] - I[k + 1]) = {2}'.format( m, h, I[k] - I[k + 1])) # skonci pri dosiahnuti presnosti if Abs(I[k] - I[k + 1]) <= e: return I[k + 1] k += 1
def babylon(n, x0, e): """ S vyuzitim Babylonskej metody vypocita odmocninu cisla n. """ assert n > 0, 'Cislo n musi byt vacsie ako nula' assert x0 > 0, 'Pociatocna hodnota x0 musi byt vacsia ako nula' assert e > 0, 'Presnost e musi byt vacsia ako nula' while True: # nova aproximacia je priemerom hodnot x0 a n / x0 x = 0.5 * (x0 + n / x0) logger.info( 'x = {0}, x0 = {1}, Abs(x - x0) = {2}'.format(x, x0, Abs(x - x0))) # skonci ak je dosiahnuta pozadovana presnost if Abs(x - x0) < e: return x x0 = x
def newton(a, b, fn, e): """ S vyuzitim Newtonovej metody vypocita koren funkcie fn na intervale <a,b>. """ assert a < b, 'Cislo b musi byt vacsie ako cislo a' assert e > 0, 'Presnost e musi byt vacsia ako nula' # urci prvu a druhu derivaciu funkcie fn_d1 = diff(fn) fn_d2 = diff(fn_d1) logger.info('fn_d1 = {0}, fn_d2 = {1}'.format(fn_d1, fn_d2)) f = lambda x: eval_expr(fn, x=x) fd = lambda x: eval_expr(fn_d1, x=x) fd2 = lambda x: eval_expr(fn_d2, x=x) # aspon jeden z bodov musi splnit podmienku # inak je potrebne upravit interval if f(a) * fd2(a) > 0: x = a elif f(b) * fd2(b) > 0: x = b else: raise ValueError('aspon jeden z bodov a alebo b musi ' 'splnat podmienku f(x) * fd2(x) > 0') while True: # vypocet priesecnika s osou x x1 = x - f(x) / fd(x) logger.info( 'x = {0}, x1 = {1}, Abs(x1 - x) = {2}'.format(x, x1, Abs(x1 - x))) # skonci pri dosiahnuti presnosti if Abs(x1 - x) <= e: return x1 x = x1