DAS_2024_1/agliullov_daniyar_lab_6/main.py
2024-12-30 21:35:39 +04:00

87 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import numpy as np
import time
from multiprocessing import Pool
np.seterr(over='ignore')
# Функция для вычисления детерминанта методом Гаусса
def compute_determinant_gauss(mat):
size = mat.shape[0]
matrix_copy = mat.astype(float) # Копируем матрицу, чтобы не изменять исходную
determinant = 1.0 # Начальное значение детерминанта
for k in range(size):
# Находим максимальный элемент в текущем столбце для уменьшения ошибок округления
max_index = np.argmax(np.abs(matrix_copy[k:size, k])) + k
if matrix_copy[max_index, k] == 0:
return 0 # Если на главной диагонали ноль, детерминант равен нулю
# Меняем местами строки
if max_index != k:
matrix_copy[[k, max_index]] = matrix_copy[[max_index, k]]
determinant *= -1 # Каждая перестановка меняет знак детерминанта
# Обнуляем элементы ниже главной диагонали
for m in range(k + 1, size):
multiplier = matrix_copy[m, k] / matrix_copy[k, k]
matrix_copy[m, k:] -= multiplier * matrix_copy[k, k:]
# Произведение элементов на главной диагонали
for j in range(size):
determinant *= matrix_copy[j, j]
return determinant
# Функция для параллельного вычисления детерминанта
def parallel_worker(index_range, mat):
size = mat.shape[0]
matrix_copy = mat.astype(float)
det = 1.0
for k in range(index_range[0], index_range[1]):
max_index = np.argmax(np.abs(matrix_copy[k:size, k])) + k
if matrix_copy[max_index, k] == 0:
return 0
if max_index != k:
matrix_copy[[k, max_index]] = matrix_copy[[max_index, k]]
det *= -1
for m in range(k + 1, size):
multiplier = matrix_copy[m, k] / matrix_copy[k, k]
matrix_copy[m, k:] -= multiplier * matrix_copy[k, k:]
return det
# Функция для параллельного вычисления детерминанта
def compute_parallel_determinant(mat, num_workers):
size = mat.shape[0]
block_size = size // num_workers
ranges = [(i * block_size, (i + 1) * block_size) for i in range(num_workers)]
with Pool(processes=num_workers) as pool:
results = pool.starmap(parallel_worker, [(block, mat) for block in ranges])
# Объединяем результаты
total_determinant = sum(results)
return total_determinant
# Функция для запуска тестов производительности
def execute_benchmarks():
sizes = [100, 300, 500] # Размеры матриц
for size in sizes:
random_matrix = np.random.rand(size, size) # Генерация случайной матрицы
print(f"--- Тест производительности для матрицы {size}x{size} ---")
# Последовательное вычисление детерминанта
start_time = time.time()
sequential_det = compute_determinant_gauss(random_matrix)
seq_duration = time.time() - start_time
print(f"Время последовательного вычисления для {size}x{size}: {seq_duration:.4f} секунд")
# Параллельное вычисление с различным количеством процессов
for workers in [1, 2, 4, 6, 8, 12, 16]:
start_time = time.time()
parallel_det = compute_parallel_determinant(random_matrix, workers)
par_duration = time.time() - start_time
speedup_ratio = seq_duration / par_duration if par_duration > 0 else 0
print(f"Параллельное время с {workers} процессами: {par_duration:.4f} секунд, Ускорение: {speedup_ratio:.2f}")
# Запуск тестов производительности
if __name__ == '__main__':
execute_benchmarks()