-
Notifications
You must be signed in to change notification settings - Fork 0
/
Multiple IndependentRun.py
134 lines (103 loc) · 4.6 KB
/
Multiple IndependentRun.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import time
import random
import pandas as pd
from statistics import mean, stdev
def split_matrix(matrix):
rows, cols = len(matrix), len(matrix[0])
split_row, split_col = rows // 2, cols // 2
A11 = [row[:split_col] for row in matrix[:split_row]]
A12 = [row[split_col:] for row in matrix[:split_row]]
A21 = [row[:split_col] for row in matrix[split_row:]]
A22 = [row[split_col:] for row in matrix[split_row:]]
return A11, A12, A21, A22
def add_matrices(matrix1, matrix2):
return [
[matrix1[i][j] + matrix2[i][j] for j in range(len(matrix1[0]))]
for i in range(len(matrix1))
]
def subtract_matrices(matrix1, matrix2):
return [
[matrix1[i][j] - matrix2[i][j] for j in range(len(matrix1[0]))]
for i in range(len(matrix1))
]
def strassen(matrix1, matrix2):
if len(matrix1) == 1:
return [[matrix1[0][0] * matrix2[0][0]]]
A11, A12, A21, A22 = split_matrix(matrix1)
B11, B12, B21, B22 = split_matrix(matrix2)
P1 = strassen(A11, subtract_matrices(B12, B22))
P2 = strassen(add_matrices(A11, A12), B22)
P3 = strassen(add_matrices(A21, A22), B11)
P4 = strassen(A22, subtract_matrices(B21, B11))
P5 = strassen(add_matrices(A11, A22), add_matrices(B11, B22))
P6 = strassen(subtract_matrices(A12, A22), add_matrices(B21, B22))
P7 = strassen(subtract_matrices(A11, A21), add_matrices(B11, B12))
C11 = subtract_matrices(add_matrices(P5, P4), subtract_matrices(P2, P6))
C12 = add_matrices(P1, P2)
C21 = add_matrices(P3, P4)
C22 = subtract_matrices(subtract_matrices(P5, P3), subtract_matrices(P1, P7))
result = [
C11[i] + C12[i]
for i in range(len(C11))
] + [
C21[i] + C22[i]
for i in range(len(C21))
]
return result
def generate_random_matrix(rows, cols, seed=None):
if seed is not None:
random.seed(seed)
return [[random.randint(1, 100) for _ in range(cols)] for _ in range(rows)]
def benchmark(matrix_size, repetitions=5, warm_up_runs=3, stress_runs=100, seed=None):
data = {'Matrix Size': [], 'Run Number': [], 'Runtime (seconds)': []}
# Warm-up phase
for _ in range(warm_up_runs):
matrix1 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
matrix2 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
strassen(matrix1, matrix2)
# Actual benchmarking
for run_number in range(1, repetitions + 1):
matrix1 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
matrix2 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
start_time = time.perf_counter()
strassen(matrix1, matrix2)
end_time = time.perf_counter()
runtime = end_time - start_time
data['Matrix Size'].append(matrix_size)
data['Run Number'].append(run_number)
data['Runtime (seconds)'].append(runtime)
df = pd.DataFrame(data)
average_runtimes = df.groupby('Matrix Size')['Runtime (seconds)'].agg([mean, stdev]).reset_index()
print("\nAverage Runtimes:\n", average_runtimes)
# Stress testing
stress_data = []
for _ in range(stress_runs):
matrix1 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
matrix2 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
start_time = time.perf_counter()
strassen(matrix1, matrix2)
end_time = time.perf_counter()
runtime = end_time - start_time
stress_data.append(runtime)
print(f"\nStress Testing for Matrix Size {matrix_size}x{matrix_size}:")
print(f"Mean Runtime: {mean(stress_data)} seconds")
print(f"Standard Deviation: {stdev(stress_data)} seconds")
return df
def multiple_independent_runs(matrix_size, independent_runs=5, repetitions=5, warm_up_runs=3, stress_runs=100, seed=None):
all_data = pd.DataFrame()
for run in range(independent_runs):
print(f"\nIndependent Run {run + 1}/{independent_runs}")
run_data = benchmark(matrix_size, repetitions=repetitions, warm_up_runs=warm_up_runs, stress_runs=stress_runs, seed=seed)
all_data = pd.concat([all_data, run_data], ignore_index=True)
return all_data
# Collect benchmark data
matrix_sizes = [2, 4, 8, 16, 32, 64, 128]
independent_runs = 3
repetitions = 5
stress_runs = 100
final_data = pd.DataFrame()
for matrix_size in matrix_sizes:
matrix_data = multiple_independent_runs(matrix_size, independent_runs=independent_runs, repetitions=repetitions, stress_runs=stress_runs)
final_data = pd.concat([final_data, matrix_data], ignore_index=True)
# Display the combined data table
print("\nCombined Data Table:\n", final_data)