Изменить в программе заранее заданный список чисел на числа, вводимые пользователем
Скорее всего отношусь к чайникам относительно питона. Просьба заключается в том, чтобы изменить программу (по методу наименьших квадратов), работающую с заранее заданными списками чисел (х и у), так, чтобы данные списки вводил пользователь. Если кол-во чисел в двух списках не совпадает, то уведомить об этом и вновь попросить ввести числа. Конечно, сама программа сделана, вероятно, некомпетентно и всё можно сделать в десятки раз проще, но хотелось бы без радикальных изменений по всей программе. Сама программу и ещё один черновик (где я пытался сам осуществить вышеописанное, но способ нагло украл и получил неработающий вариант) прилагаются.
Заранее благодарю.
import math
import matplotlib.pyplot as plt
import numpy as np
import scipy as sp # использовано только для проверки
from scipy.optimize import fsolve # см.выше
# ввод данных
x = [-7, -6.3, -5.6, -4.9, -4.2, -3.5]
y = [5, 6, 7, 8, 9, 10]
squares = list(map(lambda x: x*x, x))
cubes = list(map(lambda x: x**3, x))
fourths = list(map(lambda x: x**4, x))
lns = list(map(lambda y: np.log(y), y))
A = np.zeros((2, 2))
for i in range(2):
for j in range(2):
A[0][0] = sum(squares)
A[0][1] = sum(x)
A[1][0] = sum(x)
A[1][1] = len(x)
a = (np.linalg.det(A))
B = np.zeros((2, 2))
for i in range(2):
for j in range(2):
B[0][0] = sum(np.array(x)*np.array(y))
B[0][1] = sum(x)
B[1][0] = sum(y)
B[1][1] = len(x)
b = (np.linalg.det(B))
C = np.zeros((2, 2))
for i in range(2):
for j in range(2):
C[0][0] = sum(squares)
C[0][1] = sum(np.array(x)*np.array(y))
C[1][0] = sum(x)
C[1][1] = sum(y)
c = (np.linalg.det(C))
D = np.zeros((3, 3))
for i in range(3):
for j in range(3):
D[0][0] = sum(fourths)
D[0][1] = sum(cubes)
D[0][2] = sum(squares)
D[1][0] = sum(cubes)
D[1][1] = sum(squares)
D[1][2] = sum(x)
D[2][0] = sum(squares)
D[2][1] = sum(x)
D[2][2] = len(x)
d = (np.linalg.det(D))
E = np.zeros((3, 3))
for i in range(3):
for j in range(3):
E[0][0] = sum(np.array(squares)*np.array(y))
E[0][1] = sum(cubes)
E[0][2] = sum(squares)
E[1][0] = sum(np.array(x)*np.array(y))
E[1][1] = sum(squares)
E[1][2] = sum(x)
E[2][0] = sum(y)
E[2][1] = sum(x)
E[2][2] = len(x)
e = (np.linalg.det(E))
F = np.zeros((3, 3))
for i in range(3):
for j in range(3):
F[0][0] = sum(fourths)
F[0][1] = sum(np.array(squares)*np.array(y))
F[0][2] = sum(squares)
F[1][0] = sum(cubes)
F[1][1] = sum(np.array(x)*np.array(y))
F[1][2] = sum(x)
F[2][0] = sum(squares)
F[2][1] = sum(y)
F[2][2] = len(x)
f = (np.linalg.det(F))
G = np.zeros((3, 3))
for i in range(3):
for j in range(3):
G[0][0] = sum(fourths)
G[0][1] = sum(cubes)
G[0][2] = sum(np.array(squares)*np.array(y))
G[1][0] = sum(cubes)
G[1][1] = sum(squares)
G[1][2] = sum(np.array(x)*np.array(y))
G[2][0] = sum(squares)
G[2][1] = sum(x)
G[2][2] = sum(y)
g = (np.linalg.det(G))
L = np.zeros((2, 2))
for i in range(2):
for j in range(2):
L[0][0] = len(x)
L[0][1] = sum(x)
L[1][0] = sum(x)
L[1][1] = sum(squares)
l = (np.linalg.det(L))
M = np.zeros((2, 2))
for i in range(2):
for j in range(2):
M[0][0] = sum(lns)
M[0][1] = sum(x)
M[1][0] = sum(np.array(x)*np.array(lns))
M[1][1] = sum(squares)
m = (np.linalg.det(M))
N = np.zeros((2, 2))
for i in range(2):
for j in range(2):
N[0][0] = len(x)
N[0][1] = sum(lns)
N[1][0] = sum(x)
N[1][1] = sum(np.array(x)*np.array(lns))
n = (np.linalg.det(N))
# функции
y1 = [i*(b/a)+(c/a) for i in x]
y2 = [(i**2)*(e/d)+i*(f/d)+(g/d) for i in x]
y3 = [(m/l)*(math.e**(n/l*i)) for i in x]
# Вычисление невязок
results1 = list(map(lambda y1: y1, y1))
deltas1 = (np.array(results1)-np.array(y))
residuals1 = (np.array(deltas1)*np.array(deltas1))
results2 = list(map(lambda y2: y2, y2))
deltas2 = (np.array(results2)-np.array(y))
residuals2 = (np.array(deltas2)*np.array(deltas2))
results3 = list(map(lambda y3: y3, y3))
deltas3 = (np.array(results3)-np.array(y))
residuals3 = (np.array(deltas3)*np.array(deltas3))
if sum(residuals1) < sum(residuals2) and sum(residuals1) < sum(residuals3):
print("Линейная функция наиболее точно приближает экспериментальные данные")
elif sum(residuals2) < sum(residuals1) and sum(residuals2) < sum(residuals3):
print("Квадратичная функция наиболее точно приближает экспериментальные данные")
elif sum(residuals3) < sum(residuals1) and sum(residuals3) < sum(residuals2):
print("Экспонентальная функция наиболее точно приближает экспериментальные данные")
# Построение графиков
plt.subplot(1, 3, 1)
if sum(residuals1) < sum(residuals2) and sum(residuals1) < sum(residuals3):
plt.title("Линейная функция\n(наиболее приближённая)", color='red')
else:
plt.title("Линейная функция")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.scatter(x, y, c="red") # эмпирические данные заданы точками
plt.plot(x, y1)
plt.subplot(1, 3, 2)
if sum(residuals2) < sum(residuals1) and sum(residuals2) < sum(residuals3):
plt.title("Квадратичная функция\n(наиболее приближённая)", color='red')
else:
plt.title("Квадратичная функция")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.scatter(x, y, c="red")
plt.plot(x, y2)
plt.subplot(1, 3, 3)
if sum(residuals3) < sum(residuals1) and sum(residuals3) < sum(residuals2):
plt.title("Квадратичная функция\n(наиболее приближённая)", color='red')
else:
plt.title("Квадратичная функция")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.scatter(x, y, c="red")
plt.plot(x, y3)
plt.show()
# Проверка для квадратичной функции (через параметры модели для полинома степени d посредством scipy)
for d in range(1, 3):
fp, residuals, rank, sv, rcond = np.polyfit(x, y, d, full=True)
z = sp.poly1d(fp) # вызов функции-полинома
print(z)
import math
import matplotlib.pyplot as plt
import numpy as np
import scipy as sp # использовано только для проверки
from scipy.optimize import fsolve # см.выше
# ввод данных
print('Вводите значения x, нажимайте enter')
print(' для окончания ввода нажмите enter 2 раза')
a = int(input('-->> '))
x = []
while True:
try:
x.append(a)
a = int(input('-->> '))
except:
break
print('Вводите значения y, нажимайте enter')
print(' для окончания ввода нажмите enter 2 раза')
y = []
while True:
try:
y.append(a)
a = int(input('-->> '))
except:
break
if len(x) != len(y):
print("Ошибка - количество зависимых НЕ РАВНО количеству независимых. "
"Перезапустите программу и введите корректные данные")
print(x)
squares = list(map(lambda x: x*x, x))
cubes = list(map(lambda x: x**3, x))
fourths = list(map(lambda x: x**4, x))
lns = list(map(lambda y: np.log(y), y))
A = np.zeros((2, 2))
for i in range(2):
for j in range(2):
A[0][0] = sum(squares)
A[0][1] = sum(x)
A[1][0] = sum(x)
A[1][1] = len(x)
a = (np.linalg.det(A))
B = np.zeros((2, 2))
for i in range(2):
for j in range(2):
B[0][0] = sum(np.array(x)*np.array(y))
B[0][1] = sum(x)
B[1][0] = sum(y)
B[1][1] = len(x)
b = (np.linalg.det(B))
C = np.zeros((2, 2))
for i in range(2):
for j in range(2):
C[0][0] = sum(squares)
C[0][1] = sum(np.array(x)*np.array(y))
C[1][0] = sum(x)
C[1][1] = sum(y)
c = (np.linalg.det(C))
D = np.zeros((3, 3))
for i in range(3):
for j in range(3):
D[0][0] = sum(fourths)
D[0][1] = sum(cubes)
D[0][2] = sum(squares)
D[1][0] = sum(cubes)
D[1][1] = sum(squares)
D[1][2] = sum(x)
D[2][0] = sum(squares)
D[2][1] = sum(x)
D[2][2] = len(x)
d = (np.linalg.det(D))
E = np.zeros((3, 3))
for i in range(3):
for j in range(3):
E[0][0] = sum(np.array(squares)*np.array(y))
E[0][1] = sum(cubes)
E[0][2] = sum(squares)
E[1][0] = sum(np.array(x)*np.array(y))
E[1][1] = sum(squares)
E[1][2] = sum(x)
E[2][0] = sum(y)
E[2][1] = sum(x)
E[2][2] = len(x)
e = (np.linalg.det(E))
F = np.zeros((3, 3))
for i in range(3):
for j in range(3):
F[0][0] = sum(fourths)
F[0][1] = sum(np.array(squares)*np.array(y))
F[0][2] = sum(squares)
F[1][0] = sum(cubes)
F[1][1] = sum(np.array(x)*np.array(y))
F[1][2] = sum(x)
F[2][0] = sum(squares)
F[2][1] = sum(y)
F[2][2] = len(x)
f = (np.linalg.det(F))
G = np.zeros((3, 3))
for i in range(3):
for j in range(3):
G[0][0] = sum(fourths)
G[0][1] = sum(cubes)
G[0][2] = sum(np.array(squares)*np.array(y))
G[1][0] = sum(cubes)
G[1][1] = sum(squares)
G[1][2] = sum(np.array(x)*np.array(y))
G[2][0] = sum(squares)
G[2][1] = sum(x)
G[2][2] = sum(y)
g = (np.linalg.det(G))
L = np.zeros((2, 2))
for i in range(2):
for j in range(2):
L[0][0] = len(x)
L[0][1] = sum(x)
L[1][0] = sum(x)
L[1][1] = sum(squares)
l = (np.linalg.det(L))
M = np.zeros((2, 2))
for i in range(2):
for j in range(2):
M[0][0] = sum(lns)
M[0][1] = sum(x)
M[1][0] = sum(np.array(x)*np.array(lns))
M[1][1] = sum(squares)
m = (np.linalg.det(M))
N = np.zeros((2, 2))
for i in range(2):
for j in range(2):
N[0][0] = len(x)
N[0][1] = sum(lns)
N[1][0] = sum(x)
N[1][1] = sum(np.array(x)*np.array(lns))
n = (np.linalg.det(N))
# функции
y1 = [i*(b/a)+(c/a) for i in x]
y2 = [(i**2)*(e/d)+i*(f/d)+(g/d) for i in x]
y3 = [(m/l)*(math.e**(n/l*i)) for i in x]
# Вычисление невязок
results1 = list(map(lambda y1: y1, y1))
deltas1 = (np.array(results1)-np.array(y))
residuals1 = (np.array(deltas1)*np.array(deltas1))
results2 = list(map(lambda y2: y2, y2))
deltas2 = (np.array(results2)-np.array(y))
residuals2 = (np.array(deltas2)*np.array(deltas2))
results3 = list(map(lambda y3: y3, y3))
deltas3 = (np.array(results3)-np.array(y))
residuals3 = (np.array(deltas3)*np.array(deltas3))
if sum(residuals1) < sum(residuals2) and sum(residuals1) < sum(residuals3):
print("Линейная функция наиболее точно приближает экспериментальные данные")
elif sum(residuals2) < sum(residuals1) and sum(residuals2) < sum(residuals3):
print("Квадратичная функция наиболее точно приближает экспериментальные данные")
elif sum(residuals3) < sum(residuals1) and sum(residuals3) < sum(residuals2):
print("Экспонентальная функция наиболее точно приближает экспериментальные данные")
# Построение графиков
plt.subplot(1, 3, 1)
if sum(residuals1) < sum(residuals2) and sum(residuals1) < sum(residuals3):
plt.title("Линейная функция\n(наиболее приближённая)", color='red')
else:
plt.title("Линейная функция")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.scatter(x, y, c="red") # эмпирические данные заданы точками
plt.plot(x, y1)
plt.subplot(1, 3, 2)
if sum(residuals2) < sum(residuals1) and sum(residuals2) < sum(residuals3):
plt.title("Квадратичная функция\n(наиболее приближённая)", color='red')
else:
plt.title("Квадратичная функция")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.scatter(x, y, c="red")
plt.plot(x, y2)
plt.subplot(1, 3, 3)
if sum(residuals3) < sum(residuals1) and sum(residuals3) < sum(residuals2):
plt.title("Квадратичная функция\n(наиболее приближённая)", color='red')
else:
plt.title("Квадратичная функция")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.scatter(x, y, c="red")
plt.plot(x, y3)
plt.show()
# Проверка для квадратичной функции (через параметры модели для полинома степени d посредством scipy)
for d in range(1, 3):
fp, residuals, rank, sv, rcond = np.polyfit(x, y, d, full=True)
z = sp.poly1d(fp) # вызов функции-полинома
print(z)