Last active
November 7, 2016 23:03
-
-
Save vadim8kiselev/ee4c9de3235f125f698593934d33e1c6 to your computer and use it in GitHub Desktop.
This file contains 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
import math | |
from operator import mul | |
from decimal import getcontext, Decimal | |
getcontext().prec = 20 | |
varianta = 9 | |
accuracy = Decimal(0.00000001) | |
interval = xrange(1, 6) | |
vector = [Decimal(x) for x in [7, 3.25, 8]] | |
matrix = [[4, 1, 2], | |
[1, 0.25, 2], | |
[0, 1, 7], | |
] | |
def calc_step(value): | |
sign = calc_step.sign | |
degree = calc_step.degree | |
calc_step.sign *= -1 | |
calc_step.degree += 2 | |
return sign * Decimal((varianta * value) ** degree) / Decimal(math.factorial(degree)) if degree > 0 else 1 | |
def get_row_summary(point): | |
calc_step.sign = 1 | |
calc_step.degree = 0 | |
functional_row = [] | |
while True: | |
functional_row.append(calc_step(point)) | |
if abs(functional_row[-1]) < accuracy: | |
break | |
return sum(functional_row) | |
def get_dense_row(): | |
x = [x for x in interval] | |
y = [get_row_summary(Decimal(y)) for y in x] | |
new_x = [x[0]] | |
for index in xrange(1, len(x)): | |
new_x += [Decimal(x[index] + x[index - 1]) / 2] + [x[index]] | |
new_y = [y[0]] | |
for index in xrange(1, len(y)): | |
new_y += [Decimal(y[index] + y[index - 1]) / 2] + [y[index]] | |
return get_result(new_x, new_y) | |
def calculate_lagrange(point, x, y): | |
result = 0 | |
for k in xrange(len(x)): | |
resultStep = 1 | |
for i in xrange(len(x)): | |
if k != i: | |
resultStep *= Decimal(point - x[i]) / Decimal(x[k] - x[i]) | |
result += resultStep * Decimal(y[k]) | |
return result; | |
def calc_interpolant_in_form_Lagrange(X): | |
x = [x for x in X] | |
y = [Decimal(y) ** (len(interval) - 1) for y in x] | |
new_x = [Decimal(x[0])] | |
for index in xrange(1, len(x)): | |
new_x += [Decimal(x[index] + x[index - 1]) / 2] + [Decimal(x[index])] | |
new_y = [Decimal(y[0])] | |
for index in xrange(1, len(y)): | |
new_y += [calculate_lagrange((Decimal(x[index] + x[index - 1]) / 2), x, y)] + [Decimal(y[index])] | |
new_z = [x ** (len(interval) - 1) for x in new_x] | |
return get_result_3(new_x, new_y, new_z) | |
def calc_interpolant_in_form_Nyuton(X): | |
x = [x for x in X] | |
y = [Decimal(y) ** (len(interval) - 1) for y in x] | |
new_x = [Decimal(x[0])] | |
for index in xrange(1, len(x)): | |
new_x += [Decimal(x[index] + x[index - 1]) / 2] + [Decimal(x[index])] | |
nyuton = [[y[i]] + [0] * (len(x) - i - 1) for i in xrange(len(x))] | |
for j in xrange(1, len(nyuton)): | |
for i in xrange(len(nyuton) - j): | |
nyuton[i][j] = Decimal(nyuton[i + 1][j - 1] - nyuton[i][j - 1]) / Decimal(x[j + i] - x[i]) | |
new_z = [] | |
for k in new_x: | |
result = 0 | |
for i in xrange(len(x)): | |
step = nyuton[0][i] | |
for j in xrange(i): | |
step *= k - x[j] | |
result += step | |
new_z += [result] | |
return get_result(new_x, new_z) | |
def go_forward_stroke(): | |
for index in xrange(len(vector)): | |
if matrix[index][index] == 0: | |
slicee = [row[index] for row in matrix] | |
secret = slicee.index(max(slicee, key=abs)) | |
matrix[index], matrix[secret] = matrix[secret], matrix[index] | |
vector[index], vector[secret] = vector[secret], vector[index] | |
vector[index] = Decimal(vector[index]) / Decimal(matrix[index][index]) | |
matrix[index] = [Decimal(i) / Decimal(matrix[index][index]) for i in matrix[index]] | |
for jndex in xrange(index + 1, len(vector)): | |
subtract = Decimal(matrix[jndex][index]) / Decimal(matrix[index][index]) | |
if Decimal(matrix[index][jndex]) - Decimal(subtract) != Decimal(matrix[index][jndex]): | |
matrix[jndex] = [Decimal(matrix[jndex][special]) - Decimal(matrix[index][special]) * Decimal(subtract) for special in xrange(len(matrix[index]))] | |
vector[jndex] -= Decimal(vector[index]) | |
''' | |
for i in xrange(len(vector)): | |
for j in xrange(len(vector)): | |
print matrix[i][j], | |
print '' | |
print vector | |
''' | |
def go_reverse_motion(): | |
answer = [0] * len(vector) | |
for i in xrange(len(vector)): | |
index = len(vector) - i - 1 | |
answer[index] = vector[index] | |
for j in xrange(index + 1, len(vector)): | |
answer[index] -= answer[j] * matrix[index][j] | |
print answer | |
def get_result_callback(x, callback): | |
return [str(Decimal(point)) + ':\t {0:.20f}'.format(callback(Decimal(point))) for point in x] | |
def get_result(x, y): | |
return [str(Decimal(x[index])) + ':\t {0:.20f}'.format(y[index]) for index in xrange(len(x))] | |
def get_result_3(x, y, z): | |
return [str(Decimal(x[index])) + ':\t {0:.15f} = {0:.15f}'.format(y[index], z[index]) for index in xrange(len(x))] | |
def main(): | |
go_forward_stroke() | |
go_reverse_motion() | |
try: | |
#first task | |
#for answer in get_result_callback(interval, get_row_summary): | |
# print answer | |
#print '' | |
#second task | |
#for answer in get_dense_row(): | |
# print answer | |
#print '' | |
#third task | |
#for answer in calc_interpolant_in_form_Lagrange(interval): | |
# print answer | |
#print '' | |
#fourth task | |
#for answer in calc_interpolant_in_form_Nyuton(interval): | |
# print answer | |
#print '' | |
#fifth task | |
#for answer in calc_interpolant_in_form_Gauss(interval): | |
# print answer | |
print '' | |
except Exception, e: | |
print e | |
exit = raw_input() | |
exit = raw_input() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment