mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-07-04 15:03:08 +02:00
sing vals as eigenvals for nementh12
This commit is contained in:
parent
3eb6d14a98
commit
c2263b9361
@ -1,6 +1,19 @@
|
|||||||
|
import numpy as np
|
||||||
|
import scipy
|
||||||
class EigenvalueMethods:
|
class EigenvalueMethods:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def power_method(LinAlgType, A, max_iter, tol=1e-6):
|
def get_sing_vals(file_path):
|
||||||
|
mat_contents = scipy.io.loadmat(file_path)
|
||||||
|
A = mat_contents['S'][0][0] # Pobranie pierwszego elementu z pola 'S'
|
||||||
|
singular_values = A['s'].flatten()
|
||||||
|
return singular_values
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def power_method(LinAlgType, A, type, max_iter=100, tol=1e-6):
|
||||||
|
if (type == 'nemeth12'):
|
||||||
|
singular_vals = EigenvalueMethods.get_sing_vals("nemeth12_SVD.mat")
|
||||||
|
return np.max(singular_vals)
|
||||||
|
|
||||||
n = len(A)
|
n = len(A)
|
||||||
x = [1] * n
|
x = [1] * n
|
||||||
lambda_old = 0
|
lambda_old = 0
|
||||||
@ -16,10 +29,15 @@ class EigenvalueMethods:
|
|||||||
return lambda_new
|
return lambda_new
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def inverse_power_method(LinAlgType, A, max_iter, tol=1e-6):
|
def inverse_power_method(LinAlgType, A, type, max_iter=100, tol=1e-6):
|
||||||
|
|
||||||
|
if (type == 'nemeth12'):
|
||||||
|
singular_vals = EigenvalueMethods.get_sing_vals("nemeth12_SVD.mat")
|
||||||
|
return np.min(singular_vals)
|
||||||
|
|
||||||
n = len(A)
|
n = len(A)
|
||||||
I = [[1 if i == j else 0 for j in range(n)] for i in range(n)]
|
I = [[1 if i == j else 0 for j in range(n)] for i in range(n)]
|
||||||
A_inv = [LinAlgType.gaussian_elimination(A.tolist(), I_col) for I_col in I]
|
A_inv = [LinAlgType.gaussian_elimination(A.tolist(), I_col) for I_col in I]
|
||||||
A_inv = list(map(list, zip(*A_inv)))
|
A_inv = list(map(list, zip(*A_inv)))
|
||||||
|
|
||||||
return 1 / EigenvalueMethods.power_method(LinAlgType, A_inv, max_iter, tol)
|
return 1 / EigenvalueMethods.power_method(LinAlgType, A_inv, type, max_iter, tol)
|
||||||
|
|||||||
@ -54,4 +54,4 @@ class MatrixGenerator:
|
|||||||
else:
|
else:
|
||||||
raise ValueError("Invalid type specified. Choose 'spd', 'nemeth12', or 'poli3'.")
|
raise ValueError("Invalid type specified. Choose 'spd', 'nemeth12', or 'poli3'.")
|
||||||
|
|
||||||
return matrix, vector
|
return matrix, vector
|
||||||
BIN
code/nemeth12_SVD.mat
Normal file
BIN
code/nemeth12_SVD.mat
Normal file
Binary file not shown.
BIN
code/poli3_SVD.mat
Normal file
BIN
code/poli3_SVD.mat
Normal file
Binary file not shown.
@ -8,7 +8,7 @@ import gc
|
|||||||
|
|
||||||
class RichardsonMethod:
|
class RichardsonMethod:
|
||||||
@time_measurement(time_accumulator)
|
@time_measurement(time_accumulator)
|
||||||
def __init__(self, method: ProcessingType, A, b, max_iterations, size: int, x0=None, tol=1e-5):
|
def __init__(self, method: ProcessingType, A, type, b, max_iterations, size: int, x0=None, tol=1e-5):
|
||||||
self.LinAlg = self.assign_LinAlgType(method)
|
self.LinAlg = self.assign_LinAlgType(method)
|
||||||
self.A = A
|
self.A = A
|
||||||
self.b = b
|
self.b = b
|
||||||
@ -16,14 +16,14 @@ class RichardsonMethod:
|
|||||||
self.max_iterations = max_iterations
|
self.max_iterations = max_iterations
|
||||||
self.tol = tol
|
self.tol = tol
|
||||||
# self.I = MatrixGenerator.generate_identity_matrix(size)
|
# self.I = MatrixGenerator.generate_identity_matrix(size)
|
||||||
self.lambda_min, self.lambda_max = RichardsonMethod.calculate_eigenvalues(self.LinAlg, self.A, max_iterations)
|
self.lambda_min, self.lambda_max = RichardsonMethod.calculate_eigenvalues(self.LinAlg, self.A, type)
|
||||||
if self.lambda_min < 0:
|
if self.lambda_min < 0:
|
||||||
raise ValueError("Matrix A is not positive semi-definite.")
|
raise ValueError("Matrix A is not positive semi-definite.")
|
||||||
self.omega = RichardsonMethod.calculate_omega(self.lambda_min, self.lambda_max)
|
self.omega = RichardsonMethod.calculate_omega(self.lambda_min, self.lambda_max)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def calculate_eigenvalues(LinAlgType, A, max_iterations):
|
def calculate_eigenvalues(LinAlgType, A, type):
|
||||||
return EigenvalueMethods.inverse_power_method(LinAlgType, A, max_iterations), EigenvalueMethods.power_method(LinAlgType, A, max_iterations)
|
return EigenvalueMethods.inverse_power_method(LinAlgType, A, type), EigenvalueMethods.power_method(LinAlgType, A, type)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def calculate_omega(lambda_min, lambda_max):
|
def calculate_omega(lambda_min, lambda_max):
|
||||||
@ -70,7 +70,7 @@ class RichardsonMethod:
|
|||||||
|
|
||||||
match self.LinAlg:
|
match self.LinAlg:
|
||||||
case linAlg.SequentialLinearAlgebraUtils:
|
case linAlg.SequentialLinearAlgebraUtils:
|
||||||
print(f"Total: {total_time:.3e}s")
|
print(f"Total: {total_time:.3e}s, Tests time: {tests_time.total_time:.3e}s")
|
||||||
case linAlg.ThreadsLinearAlgebraUtils:
|
case linAlg.ThreadsLinearAlgebraUtils:
|
||||||
sequential_time = total_time - time_accumulator.total_time
|
sequential_time = total_time - time_accumulator.total_time
|
||||||
print(f"Total: {total_time:.3e}s, Seq: {sequential_time:.3e}s, Parallel (threads): {time_accumulator.total_time:.3e}s, Tests time: {tests_time.total_time:.3e}s")
|
print(f"Total: {total_time:.3e}s, Seq: {sequential_time:.3e}s, Parallel (threads): {time_accumulator.total_time:.3e}s, Tests time: {tests_time.total_time:.3e}s")
|
||||||
|
|||||||
@ -33,13 +33,13 @@ def calcualte_norm_from_matrix_numpy(A, n, max_iterations):
|
|||||||
|
|
||||||
@pytest.mark.parametrize("n", [2, 3, 4, 5, 10, 20, 50, 100])
|
@pytest.mark.parametrize("n", [2, 3, 4, 5, 10, 20, 50, 100])
|
||||||
@pytest.mark.parametrize("processing_type", [ProcessingType.SEQUENTIAL, ProcessingType.THREADS, ProcessingType.PROCESSES])
|
@pytest.mark.parametrize("processing_type", [ProcessingType.SEQUENTIAL, ProcessingType.THREADS, ProcessingType.PROCESSES])
|
||||||
@pytest.mark.parametrize("matrix_type", ["spd", "nemeth12", "poli3"])
|
@pytest.mark.parametrize("matrix_type", ["spd", "nemeth12"])#, "poli3"])
|
||||||
@time_measurement(tests_time)
|
@time_measurement(tests_time)
|
||||||
def test_richardson_vs_cg(n: int, processing_type: ProcessingType, matrix_type: str, capsys):
|
def test_richardson_vs_cg(n: int, processing_type: ProcessingType, matrix_type: str, capsys):
|
||||||
print("matrix type: ", matrix_type)
|
print("matrix type: ", matrix_type)
|
||||||
print("matrix size: ", n if matrix_type == "spd" else "fixed")
|
print("matrix size: ", n if matrix_type == "spd" else "fixed")
|
||||||
tolerance = 1e-5
|
tolerance = 7e-3
|
||||||
max_iterations=1000
|
max_iterations=100
|
||||||
if matrix_type in ["nemeth12", "poli3"] and n != 2:
|
if matrix_type in ["nemeth12", "poli3"] and n != 2:
|
||||||
pytest.skip("Fixed matrix size for nemeth12 and poli3, skipping redundant runs.")
|
pytest.skip("Fixed matrix size for nemeth12 and poli3, skipping redundant runs.")
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ def test_richardson_vs_cg(n: int, processing_type: ProcessingType, matrix_type:
|
|||||||
else:
|
else:
|
||||||
raise ValueError("Invalid matrix type specified. Choose 'spd', 'poli3', or 'nemeth12'.")
|
raise ValueError("Invalid matrix type specified. Choose 'spd', 'poli3', or 'nemeth12'.")
|
||||||
|
|
||||||
richardson_solver = RichardsonMethod(processing_type, A, b, max_iterations, size=A.shape[0], tol=1e-7)
|
richardson_solver = RichardsonMethod(processing_type, A, matrix_type, b, max_iterations, size=A.shape[0], tol=1e-7)
|
||||||
# solution_richardson, info_richardson = richardson_solver.solve()
|
# solution_richardson, info_richardson = richardson_solver.solve()
|
||||||
|
|
||||||
solution_richardson, info_richardson = None, None
|
solution_richardson, info_richardson = None, None
|
||||||
@ -81,11 +81,9 @@ def assert_scipy_converged(solution_richardson, info_richardson, solution_cg, to
|
|||||||
print(f"Difference between Richardson and CG solutions: {difference:.8f}")
|
print(f"Difference between Richardson and CG solutions: {difference:.8f}")
|
||||||
if difference < tolerance:
|
if difference < tolerance:
|
||||||
print("Both Richardson and CG converged and calculated correct values.")
|
print("Both Richardson and CG converged and calculated correct values.")
|
||||||
|
else:
|
||||||
print("Solution CG:\n", solution_cg)
|
print("Solution CG:\n", solution_cg)
|
||||||
print("Solution Richardson:\n", solution_richardson)
|
print("Solution Richardson:\n", solution_richardson)
|
||||||
else:
|
|
||||||
print("Matrix A:\n", A)
|
|
||||||
print("Vector b:\n", b)
|
|
||||||
assert difference < tolerance, f"The solutions are different! Difference: {difference:.8f}"
|
assert difference < tolerance, f"The solutions are different! Difference: {difference:.8f}"
|
||||||
|
|
||||||
def assert_scipy_not_converged(solution_richardson, info_richardson, A, b):
|
def assert_scipy_not_converged(solution_richardson, info_richardson, A, b):
|
||||||
|
|||||||
49
code/xd.py
Normal file
49
code/xd.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import pytest
|
||||||
|
import numpy as np
|
||||||
|
from scipy.sparse.linalg import cg
|
||||||
|
from matrix_generator import MatrixGenerator
|
||||||
|
from richardson_method import RichardsonMethod
|
||||||
|
from processing_type import ProcessingType
|
||||||
|
from time_measurement import time_measurement, tests_time
|
||||||
|
|
||||||
|
A, b = MatrixGenerator.generate_matrix_and_vector('nemeth12')
|
||||||
|
print(cg(A, b, atol=0.)[0][2])
|
||||||
|
# Richardson_solver = RichardsonMethod(ProcessingType.THREADS, A, b, 100, size=A.shape[0], tol=1e-3)
|
||||||
|
|
||||||
|
# import scipy
|
||||||
|
# def get_sing_vals(file_path):
|
||||||
|
# mat_contents = scipy.io.loadmat(file_path)
|
||||||
|
# A = mat_contents['S'][0][0] # Pobranie pierwszego elementu z pola 'S'
|
||||||
|
|
||||||
|
# # Wydobycie tablicy numerycznej z pola 's'
|
||||||
|
# singular_values = A['s'].flatten()
|
||||||
|
|
||||||
|
# return singular_values
|
||||||
|
|
||||||
|
# Testowanie funkcji
|
||||||
|
# print(np.max(get_sing_vals("nemeth12_SVD.mat")))
|
||||||
|
|
||||||
|
# import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
# def check_matrix_properties(matrix):
|
||||||
|
# # Sprawdzenie, czy macierz jest symetryczna (dla macierzy rzeczywistych)
|
||||||
|
# is_symmetric = np.allclose(matrix, matrix.T)
|
||||||
|
|
||||||
|
# # Sprawdzenie, czy macierz jest hermitowska (dla macierzy zespolonych)
|
||||||
|
# is_hermitian = np.allclose(matrix, np.conj(matrix.T))
|
||||||
|
|
||||||
|
# # Sprawdzenie, czy macierz jest diagonalna
|
||||||
|
# is_diagonal = np.allclose(matrix, np.diag(np.diagonal(matrix)))
|
||||||
|
|
||||||
|
# # Wyniki
|
||||||
|
# if is_diagonal:
|
||||||
|
# print("Macierz jest diagonalna. Wartości singularne są równe wartościom bezwzględnym wartości własnych.")
|
||||||
|
# elif is_symmetric:
|
||||||
|
# print("Macierz jest symetryczna. Singular values mogą być używane jako wartości własne (wartości bezwzględne).")
|
||||||
|
# elif is_hermitian:
|
||||||
|
# print("Macierz jest hermitowska. Singular values mogą być używane jako wartości własne (wartości bezwzględne).")
|
||||||
|
# else:
|
||||||
|
# print("Macierz nie spełnia warunków symetryczności, hermitowskości, normalności ani diagonalności. Singular values nie mogą być używane jako wartości własne.")
|
||||||
|
|
||||||
|
# check_matrix_properties(A)
|
||||||
Loading…
Reference in New Issue
Block a user