1
0
skaitiniai-metodai-labs/Lab3/part_1.py
2023-12-21 15:50:48 +02:00

164 lines
5.2 KiB
Python

from math import cos, sin, pi
import matplotlib.pyplot as plt
from dataclasses import dataclass
import numpy as np
@dataclass
class Lygtis:
koeficientai: list[float]
rezultatas: list[float]
@dataclass
class LygciuSistema:
lygtys: list[Lygtis]
def lerp(x, min_x, max_x):
return min_x + x * (max_x - min_x)
def gauti_sklaida(lygciu_sistema: LygciuSistema, x, rezultato_idx=0):
n = lygciu_sistema.lygtys[0].koeficientai
sklaida = 0
for lygtis in lygciu_sistema.lygtys:
issistatyta = sum(x[i]*lygtis.koeficientai[i] for i in range(len(n)))
sklaida += abs(issistatyta - lygtis.rezultatas[rezultato_idx])
return sklaida
def gauso_atispindzio_metodas(lygciu_sistema: LygciuSistema, epsilon=1e-7):
koeficientai = list(lygtis.koeficientai for lygtis in lygciu_sistema.lygtys)
A = np.matrix(koeficientai).astype(float)
rezultatai = list(lygtis.rezultatas for lygtis in lygciu_sistema.lygtys)
b = np.matrix(rezultatai).astype(float)
n = (np.shape(A))[0]
nb = (np.shape(b))[1]
A1 = np.hstack((A, b))
# tiesioginis etapas(atspindziai):
for i in range(0, n - 1):
z = A1[i:n, i]
zp = np.zeros(np.shape(z))
zp[0] = np.linalg.norm(z)
omega = z - zp
omega = omega / np.linalg.norm(omega)
Q = np.identity(n - i) - 2 * omega * omega.transpose()
A1[i:n, :] = Q.dot(A1[i:n, :])
if np.sum(np.abs(A1[n-1, 0:n-nb+1])) < epsilon:
return None
# atgalinis etapas:
x = np.zeros(shape=(n, 1))
for i in range(n - 1, -1, -1):
x[i, :] = (A1[i, n:n + nb] - A1[i, i + 1:n] * x[i + 1:n, :]) / A1[i, i]
return list(x.flat)
def gauti_x_taskus(from_x, to_x, density) -> list[float]:
x_s = []
for i in range(density):
x_s.append(lerp(float(i) / (density-1), from_x, to_x))
return x_s
def gauti_xy_taskus(F, from_x, to_x, density) -> tuple[list[float], list[float]]:
x_s = gauti_x_taskus(from_x, to_x, density)
y_s = []
for x in x_s:
y_s.append(F(x))
return (x_s, y_s)
def plot_function(F, from_x, to_x, density, **kvargs):
x_s, y_s = gauti_xy_taskus(F, from_x, to_x, density)
plt.plot(x_s, y_s, **kvargs)
def gauti_vienanario_sprendinius(x_mazgai: list[float], y_mazgai: list[float]) -> list[float]:
lygtys = []
for i, y in enumerate(y_mazgai):
koeficientai = []
x = x_mazgai[i]
for j in range(len(x_mazgai)):
koeficientai.append(x ** j)
lygtys.append(Lygtis(koeficientai, [y]))
return gauso_atispindzio_metodas(LygciuSistema(lygtys))
def gauti_y_is_vienanariu(vienanariai: list[float], x: float):
y = 0
for i, a in enumerate(vienanariai):
y += a * x ** i
return y
def gauti_ciobysevo_abscises(n: int) -> list[float]:
x_s = []
for i in range(n):
x = cos(pi*(2*i + 1) / (2*n))
x_s.append(x)
return x_s
def konvertuoti_is_ciobysevo(abscises: list[float], a: float, b: float) -> list[float]:
X_s = []
for x in abscises:
X = (a+b)/2 + (b-a)/2*x
X_s.append(X)
return X_s
def gauti_vienanariu_paklaidas(F, x_s: list[float], vienanariai):
paklaidos = []
for x in x_s:
interpoliuotas_y = gauti_y_is_vienanariu(vienanariai, x)
tikras_y = F(x)
paklaidos.append(abs(interpoliuotas_y - tikras_y))
return paklaidos
def plot_vienanariu_palyginima(F, x_s: list[float], vienanariai):
plt.plot(x_s, list(F(x) for x in x_s), color="blue", label="Tikrasis")
y_interpoliuotas = list(gauti_y_is_vienanariu(vienanariai, x) for x in x_s)
plt.plot(x_s, y_interpoliuotas, color="red", label="Interpoliuotas")
plt.legend()
plt.xlabel("x")
plt.ylabel("y")
plt.title("Interpoliuotas vs originalus")
def plot_vienanariu_paklaida(F, x_s: list[float], vienanariai):
y_paklaida = gauti_vienanariu_paklaidas(F, x_s, vienanariai)
plt.plot(x_s, y_paklaida, color="red")
plt.xlabel("x")
plt.ylabel("paklaida")
plt.title("Paklaida")
def main(F, x_range, mazgu_kiekis, tarpiniai_taskai):
from_x, to_x = x_range
if False:
mazgai = gauti_xy_taskus(F, from_x, to_x, mazgu_kiekis)
vienanariai = gauti_vienanario_sprendinius(mazgai[0], mazgai[1])
x_s = gauti_x_taskus(from_x, to_x, tarpiniai_taskai)
#plt.plot(mazgai[0], mazgai[1], "o", label="Mazgas")
#plot_vienanariu_palyginima(F, x_s, vienanariai)
plot_vienanariu_paklaida(F, x_s, vienanariai)
print("Paklaida:", sum(gauti_vienanariu_paklaidas(F, x_s, vienanariai)))
if True:
ciobysevo_abscises = gauti_ciobysevo_abscises(mazgu_kiekis)
x_mazgai = konvertuoti_is_ciobysevo(ciobysevo_abscises, to_x, from_x)
y_mazgai = list(F(x) for x in x_mazgai)
vienanariai = gauti_vienanario_sprendinius(x_mazgai, y_mazgai)
x_s = gauti_x_taskus(from_x, to_x, tarpiniai_taskai)
plt.plot(x_mazgai, y_mazgai, "o", label="Mazgas")
plot_vienanariu_palyginima(F, x_s, vienanariai)
#plot_vienanariu_paklaida(F, x_s, vienanariai)
print("Paklaida:", sum(gauti_vienanariu_paklaidas(F, x_s, vienanariai)))
plt.show()
main(
F = lambda x: cos(2*x) * (sin(3*x) + 1.5) - cos(x/5),
x_range = (-2, 3),
mazgu_kiekis = 10,
tarpiniai_taskai = 200
)