2024-11-26 19:08:28 +04:00
|
|
|
|
from multiprocessing import Pool, cpu_count
|
|
|
|
|
import time
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def determinant(matrix):
|
|
|
|
|
matrix = np.array(matrix, dtype=float)
|
|
|
|
|
n = matrix.shape[0]
|
|
|
|
|
|
|
|
|
|
for i in range(n):
|
|
|
|
|
if matrix[i, i] == 0:
|
|
|
|
|
for j in range(i + 1, n):
|
|
|
|
|
if matrix[j, i] != 0:
|
|
|
|
|
matrix[[i, j]] = matrix[[j, i]]
|
|
|
|
|
break
|
|
|
|
|
if matrix[i, i] == 0:
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
for j in range(i + 1, n):
|
|
|
|
|
factor = matrix[j, i] / matrix[i, i]
|
|
|
|
|
matrix[j] -= factor * matrix[i]
|
|
|
|
|
|
|
|
|
|
det = 1.0
|
|
|
|
|
for i in range(n):
|
|
|
|
|
det *= matrix[i, i]
|
|
|
|
|
return det
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _determinant_parallel_chunk(args):
|
|
|
|
|
matrix, start_row, end_row = args
|
|
|
|
|
n = matrix.shape[0]
|
|
|
|
|
for i in range(start_row, end_row):
|
|
|
|
|
for j in range(i + 1, n):
|
|
|
|
|
factor = matrix[j, i] / matrix[i, i]
|
|
|
|
|
matrix[j] -= factor * matrix[i]
|
|
|
|
|
return matrix
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def determinant_parallel(matrix, num_processes=None):
|
|
|
|
|
if num_processes is None:
|
|
|
|
|
num_processes = cpu_count()
|
|
|
|
|
|
|
|
|
|
matrix = np.array(matrix, dtype=float)
|
|
|
|
|
n = matrix.shape[0]
|
|
|
|
|
|
|
|
|
|
chunk_size = n // num_processes
|
|
|
|
|
tasks = [
|
|
|
|
|
(
|
|
|
|
|
matrix.copy(),
|
|
|
|
|
i * chunk_size,
|
|
|
|
|
(i + 1) * chunk_size if i != num_processes - 1 else n,
|
|
|
|
|
)
|
|
|
|
|
for i in range(num_processes)
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
with Pool(processes=num_processes) as pool:
|
|
|
|
|
results = pool.map(_determinant_parallel_chunk, tasks)
|
|
|
|
|
|
|
|
|
|
# В каждой части делаем лишь частичное вычитание
|
|
|
|
|
# Теперь выполняем окончательное вычисление детерминанта
|
|
|
|
|
det = 1.0
|
|
|
|
|
for i in range(n):
|
|
|
|
|
det *= results[0][i, i]
|
|
|
|
|
return det
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sizes = [100, 300, 500]
|
2024-11-26 19:13:56 +04:00
|
|
|
|
NUM_PROCESSES = 12
|
2024-11-26 19:08:28 +04:00
|
|
|
|
|
|
|
|
|
for size in sizes:
|
|
|
|
|
A = np.random.rand(size, size)
|
|
|
|
|
start_time = time.time()
|
|
|
|
|
det_seq = determinant(A)
|
|
|
|
|
seq_time = time.time() - start_time
|
|
|
|
|
|
|
|
|
|
start_time = time.time()
|
2024-11-26 19:13:56 +04:00
|
|
|
|
det_par = determinant_parallel(A, num_processes=NUM_PROCESSES)
|
2024-11-26 19:08:28 +04:00
|
|
|
|
par_time = time.time() - start_time
|
|
|
|
|
|
|
|
|
|
print(
|
|
|
|
|
f"Size {size}x{size}: Sequential Time = {seq_time:.4f} s, Parallel Time = {par_time:.4f} s"
|
|
|
|
|
)
|