1
0
skaitiniai-metodai-labs/Lab2/main_1.py
2023-11-27 23:05:39 +02:00

191 lines
6.1 KiB
Python

from dataclasses import dataclass
import numpy as np
from typing import List
# Variantas: 10
@dataclass
class Lygtis:
koeficientai: list[float]
rezultatas: List[float]
@dataclass
class LygciuSistema:
lygtys: list[Lygtis]
def swap_lygtis(lygciu_sistema: LygciuSistema, i, j):
tmp = lygciu_sistema.lygtys[i]
lygciu_sistema.lygtys[i] = lygciu_sistema.lygtys[j]
lygciu_sistema.lygtys[j] = tmp
def switch_leading(lygciu_sistema: LygciuSistema):
for i in range(len(lygciu_sistema.lygtys)):
if lygciu_sistema.lygtys[i].koeficientai[i] != 0: continue
for j in range(len(lygciu_sistema.lygtys)):
if lygciu_sistema.lygtys[j].koeficientai[i] == 0: continue
swap_lygtis(lygciu_sistema, i, j)
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:
if abs(A1[n-1, n]) < epsilon:
print("Be galo daug sprendiniu")
else:
print("Nera sprendiniu")
return
# 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]
print("Sprendinys:")
for i in range(0, n):
print(f"x{i} = {x[i, 0]:.5f}")
print("Sklaida:", gauti_sklaida(lygciu_sistema, list(x.flat)))
def paprastu_iteraciju_metodas(lygciu_sistema: LygciuSistema, epsilon=1e-12, alpha=1, iteraciju_kiekis=1000):
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]
alpha_mat = np.array([alpha, alpha, alpha, alpha]) # laisvai parinkti metodo parametrai
Atld = np.diag(1.0/np.diag(A)).dot(A) - np.diag(alpha_mat)
btld = np.diag(1.0/np.diag(A)).dot(b)
x = np.zeros(shape = (n,1))
x1 = np.zeros(shape = (n,1))
for iteracija in range(iteraciju_kiekis):
x1 = ((btld - Atld.dot(x)).transpose()/alpha_mat).transpose()
prec = np.linalg.norm(x1 - x)/(np.linalg.norm(x) + np.linalg.norm(x1))
if prec < epsilon: break
x[:]=x1[:]
print("Reikiamas iteraciju skaicius", iteracija)
print("Sprendinys:")
for i in range(0, n):
print(f"x{i} = {x[i, 0]:.5f}")
print("Sklaida:", gauti_sklaida(lygciu_sistema, list(x.flat)))
def lu_sklaidos_metodas(lygciu_sistema: LygciuSistema):
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]
P = np.arange(0, n)
# tiesioginis etapas:
for i in range(n-1):
iii = abs(A[i:n,i]).argmax()
A[[i,i+iii],:] = A[[i+iii,i],:] # sukeiciamos eilutes
P[[i,i+iii]] = P[[i+iii,i]] # sukeiciami eiluciu numeriai
for j in range (i+1,n):
r = A[j,i]/A[i,i]
A[j,i:n+1] = A[j,i:n+1] - A[i,i:n+1]*r;
A[j,i] = r
b = b[P]
# 1-as atgalinis etapas, sprendziama Ly=b, y->b
for i in range(1, n):
b[i] = b[i] - A[i,0:i]*b[0:i]
# 2-as atgalinis etapas , sprendziama Ux=b, x->b
for i in range (n-1,-1,-1) :
b[i] = (b[i] - A[i,i+1:n]*b[i+1:n])/A[i,i]
print("Sprediniai:")
for i, column in enumerate(b.transpose()):
print(f"{i+1}.")
if not np.isfinite(column).all():
print(" Nera arba be galo daug sprendiniu")
continue
for j in range(0, n):
print(f" x{j} = {column[0, j]:.5f}")
print(f" Sklaida = {gauti_sklaida(lygciu_sistema, list(column.flat), i)}")
def a_dalis(lygciu_sistemos: list[LygciuSistema]):
for lygciu_sistema in lygciu_sistemos:
switch_leading(lygciu_sistema)
print("=========== Atspindzio metodas ==========")
for i, lygciu_sistema in enumerate(lygciu_sistemos):
print("-------- Lygciu sistema ", i+1)
gauso_atispindzio_metodas(lygciu_sistema)
print("========== Paprastu iteraciju ===========")
paprastu_iteraciju_metodas(lygciu_sistemos[0])
def b_dalis(lygciu_sistema: LygciuSistema):
print("============= LU sklaidos ===============")
lu_sklaidos_metodas(lygciu_sistema)
a_dalis([
# 8
LygciuSistema([
Lygtis([ 4, 3, -1, 1], [ 12]),
Lygtis([ 3, 9, -2, -2], [ 10]),
Lygtis([-1, -2, 11, -1], [-28]),
Lygtis([ 1, -2, -1, 5], [ 16]),
]),
# 13
LygciuSistema([
Lygtis([1, -2, 3, 4], [11]),
Lygtis([0, -7, 3, 1], [ 2]),
Lygtis([1, 0, -1, 1], [-4]),
Lygtis([2, -2, 2, 5], [ 7]),
]),
# 20
LygciuSistema([
Lygtis([ 2, 4, 6, -2], [2]),
Lygtis([ 1, 3, 1, -3], [1]),
Lygtis([ 1, 1, 5, 1], [7]),
Lygtis([ 2, 3, -3, -2], [2]),
])
])
b_dalis(
# 10
LygciuSistema([
Lygtis([ 6, 1, 3, -2], [ 8, 67, -5.25]),
Lygtis([ 6, 8, 1, -1], [14, 77, 0 ]),
Lygtis([12, -2, 4, -1], [13, 126, -13.5 ]),
Lygtis([ 8, 1, 1, 5], [15, 95, -7.25]),
])
)