This repository was archived by the owner on May 9, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathperformance_test.cpp
More file actions
237 lines (190 loc) · 8.86 KB
/
performance_test.cpp
File metadata and controls
237 lines (190 loc) · 8.86 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <chrono>
#include <cmath>
#include <random>
#include "matrix_modules/matrix_operations.h"
#include "matrix_modules/verify_positive_definite_matrix.h"
#include "LUP/LUP_solver.h"
#include "SOR/SOR_solver.h"
#include "CG/CG_solver.h"
// Function to generate a symmetric positive definite matrix of size n
std::vector<std::vector<double>> generateSPDMatrix(int n) {
// Create a random matrix
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(-1.0, 1.0);
std::vector<std::vector<double>> A(n, std::vector<double>(n, 0.0));
// Generate a random matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
A[i][j] = dis(gen);
}
}
// Make it symmetric: A = (A + A^T)/2
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
double avg = (A[i][j] + A[j][i]) / 2.0;
A[i][j] = A[j][i] = avg;
}
}
// Make it positive definite: A = A + n*I
// This ensures diagonal dominance, which guarantees positive definiteness
for (int i = 0; i < n; i++) {
A[i][i] += n;
}
return A;
}
// Function to generate a random right-hand side vector of size n
std::vector<double> generateRandomVector(int n) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(-10.0, 10.0);
std::vector<double> b(n);
for (int i = 0; i < n; i++) {
b[i] = dis(gen);
}
return b;
}
// Function to write matrix to input file
void writeInputFile(const std::vector<std::vector<double>>& A, const std::vector<double>& b, int n, int method, double sorWeight, double epsilon, int maxIter) {
std::string filename = "input_n" + std::to_string(n) + ".txt";
std::ofstream inputFile(filename);
if (!inputFile) {
std::cerr << "Error opening input file: " << filename << std::endl;
return;
}
// Write method flag and SOR weight
inputFile << method << " " << sorWeight << std::endl;
// Write stopping criterion and max iterations
inputFile << epsilon << " " << maxIter << std::endl;
// Write matrix order
inputFile << n << std::endl;
// Write matrix A
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
inputFile << A[i][j] << " ";
}
inputFile << std::endl;
}
// Write vector b
for (int i = 0; i < n; i++) {
inputFile << b[i] << " ";
}
inputFile << std::endl;
inputFile.close();
}
int main() {
std::ofstream resultsFile("performance_results.txt");
if (!resultsFile) {
std::cerr << "Error opening results file!" << std::endl;
return 1;
}
// Parameters for solver
double epsilon = 1e-4;
int maxIter = 10000;
double sorWeight = 1.5; // Optimized SOR weight
// Matrix sizes to test
std::vector<int> sizes = {32, 64, 128, 512, 1024};
// Results storage
std::vector<int> sorIterations;
std::vector<int> cgIterations;
std::vector<double> lupTimes;
std::vector<double> sorTimes;
std::vector<double> cgTimes;
resultsFile << "Performance Comparison of LUP, SOR, and CG Methods" << std::endl;
resultsFile << "==================================================" << std::endl << std::endl;
resultsFile << "Stopping criterion: " << epsilon << std::endl;
resultsFile << "Maximum iterations: " << maxIter << std::endl;
resultsFile << "SOR weight: " << sorWeight << std::endl << std::endl;
resultsFile << std::setw(10) << "Size" << std::setw(15) << "SOR Iter"
<< std::setw(15) << "CG Iter" << std::setw(20) << "LUP Time(ms)"
<< std::setw(20) << "SOR Time(ms)" << std::setw(20) << "CG Time(ms)" << std::endl;
resultsFile << std::string(100, '-') << std::endl;
for (int n : sizes) {
std::cout << "Testing matrix size: " << n << std::endl;
// Generate SPD matrix and RHS vector
auto A = generateSPDMatrix(n);
auto b = generateRandomVector(n);
// Write input to file for each method
writeInputFile(A, b, n, 0, sorWeight, epsilon, maxIter); // For LUP
// Run LUP method
std::vector<double> x_lup(n, 0.0);
double maxResidual;
auto lup_start = std::chrono::high_resolution_clock::now();
bool lup_success = solveLUP(A, b, x_lup, maxResidual);
auto lup_end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> lup_elapsed_sec = lup_end - lup_start;
double lup_elapsed_ms = lup_elapsed_sec.count() * 1000.0;
lupTimes.push_back(lup_elapsed_ms);
// Run SOR method
std::vector<double> x_sor(n, 0.0);
int sor_iterations;
double sor_residual;
auto sor_start = std::chrono::high_resolution_clock::now();
bool sor_converged = solveSOR(A, b, x_sor, sorWeight, epsilon, maxIter, sor_iterations, sor_residual);
auto sor_end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> sor_elapsed_sec = sor_end - sor_start;
double sor_elapsed_ms = sor_elapsed_sec.count() * 1000.0;
sorTimes.push_back(sor_elapsed_ms);
sorIterations.push_back(sor_iterations);
// Run CG method
std::vector<double> x_cg(n, 0.0);
int cg_iterations;
double cg_residual;
auto cg_start = std::chrono::high_resolution_clock::now();
bool cg_converged = solveCG(A, b, x_cg, epsilon, maxIter, cg_iterations, cg_residual);
auto cg_end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> cg_elapsed_sec = cg_end - cg_start;
double cg_elapsed_ms = cg_elapsed_sec.count() * 1000.0;
cgTimes.push_back(cg_elapsed_ms);
cgIterations.push_back(cg_iterations);
// Write result for this size
resultsFile << std::setw(10) << n
<< std::setw(15) << sor_iterations
<< std::setw(15) << cg_iterations
<< std::fixed << std::setprecision(8)
<< std::setw(20) << lup_elapsed_ms
<< std::setw(20) << sor_elapsed_ms
<< std::setw(20) << cg_elapsed_ms
<< std::endl;
// Record detailed results for each size
resultsFile << std::endl << "Detailed results for n = " << n << ":" << std::endl;
resultsFile << "----------------------------------------" << std::endl;
// LUP details
resultsFile << "LUP Method:" << std::endl;
resultsFile << " - Maximum absolute residual: " << std::scientific << std::setprecision(8) << maxResidual << std::endl;
resultsFile << " - Direct solution (no iterations)" << std::endl;
resultsFile << " - Execution time: " << std::fixed << std::setprecision(8) << lup_elapsed_ms << " milliseconds" << std::endl << std::endl;
// SOR details
resultsFile << "SOR Method:" << std::endl;
resultsFile << " - Relaxation parameter (omega): " << sorWeight << std::endl;
resultsFile << " - Iterations performed: " << sor_iterations << std::endl;
resultsFile << " - Final residual norm: " << std::scientific << std::setprecision(8) << sor_residual << std::endl;
resultsFile << " - Execution time: " << std::fixed << std::setprecision(8) << sor_elapsed_ms << " milliseconds" << std::endl << std::endl;
// CG details
resultsFile << "CG Method:" << std::endl;
resultsFile << " - Iterations performed: " << cg_iterations << std::endl;
resultsFile << " - Final residual norm: " << std::scientific << std::setprecision(8) << cg_residual << std::endl;
resultsFile << " - Execution time: " << std::fixed << std::setprecision(8) << cg_elapsed_ms << " milliseconds" << std::endl << std::endl;
// Solution comparison
double solution_diff_lup_cg = 0.0;
double solution_diff_lup_sor = 0.0;
for (int i = 0; i < n; i++) {
solution_diff_lup_cg = std::max(solution_diff_lup_cg, std::abs(x_lup[i] - x_cg[i]));
solution_diff_lup_sor = std::max(solution_diff_lup_sor, std::abs(x_lup[i] - x_sor[i]));
}
resultsFile << "Solution Comparison:" << std::endl;
resultsFile << " - Maximum difference between LUP and CG solutions: "
<< std::scientific << std::setprecision(8) << solution_diff_lup_cg << std::endl;
resultsFile << " - Maximum difference between LUP and SOR solutions: "
<< std::scientific << std::setprecision(8) << solution_diff_lup_sor << std::endl;
resultsFile << std::endl << std::string(50, '-') << std::endl << std::endl;
}
resultsFile.close();
std::cout << "Performance testing complete. Results saved to performance_results.txt" << std::endl;
std::cout << "Input matrices saved to input_n*.txt files" << std::endl;
return 0;
}