euler314 commited on
Commit
764f20d
Β·
verified Β·
1 Parent(s): 10e2411

Update app.cpp

Browse files
Files changed (1) hide show
  1. app.cpp +165 -111
app.cpp CHANGED
@@ -1,4 +1,4 @@
1
- // app.cpp - Modified version for command line arguments
2
  #include <opencv2/opencv.hpp>
3
  #include <algorithm>
4
  #include <cmath>
@@ -12,6 +12,7 @@
12
  #include <string>
13
  #include <fstream>
14
  #include <complex>
 
15
 
16
  // Struct to hold cubic equation roots
17
  struct CubicRoots {
@@ -23,21 +24,35 @@ struct CubicRoots {
23
  // Function to solve cubic equation: az^3 + bz^2 + cz + d = 0
24
  CubicRoots solveCubic(double a, double b, double c, double d) {
25
  // Handle special case for a == 0 (quadratic)
26
- if (std::abs(a) < 1e-14) {
 
27
  CubicRoots roots;
28
  // For a quadratic equation: bz^2 + cz + d = 0
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  double discriminant = c * c - 4.0 * b * d;
30
  if (discriminant >= 0) {
31
  double sqrtDiscriminant = std::sqrt(discriminant);
32
  roots.root1 = std::complex<double>((-c + sqrtDiscriminant) / (2.0 * b), 0.0);
33
  roots.root2 = std::complex<double>((-c - sqrtDiscriminant) / (2.0 * b), 0.0);
34
- roots.root3 = std::complex<double>(1e99, 0.0); // Infinity for third root
35
  } else {
36
  double real = -c / (2.0 * b);
37
  double imag = std::sqrt(-discriminant) / (2.0 * b);
38
  roots.root1 = std::complex<double>(real, imag);
39
  roots.root2 = std::complex<double>(real, -imag);
40
- roots.root3 = std::complex<double>(1e99, 0.0); // Infinity for third root
41
  }
42
  return roots;
43
  }
@@ -61,7 +76,7 @@ CubicRoots solveCubic(double a, double b, double c, double d) {
61
 
62
  CubicRoots roots;
63
 
64
- if (D > 1e-10) { // One real root and two complex conjugate roots
65
  double sqrtD = std::sqrt(D);
66
  double u = std::cbrt(-q1 / 2.0 + sqrtD);
67
  double v = std::cbrt(-q1 / 2.0 - sqrtD);
@@ -75,7 +90,7 @@ CubicRoots solveCubic(double a, double b, double c, double d) {
75
  roots.root2 = std::complex<double>(real_part, imag_part);
76
  roots.root3 = std::complex<double>(real_part, -imag_part);
77
  }
78
- else if (D < -1e-10) { // Three distinct real roots
79
  double angle = std::acos(-q1 / 2.0 * std::sqrt(-27.0 / (p1 * p1 * p1)));
80
  double magnitude = 2.0 * std::sqrt(-p1 / 3.0);
81
 
@@ -101,7 +116,7 @@ std::vector<std::vector<double>> computeImSVsZ(double a, double y, double beta,
101
  std::vector<double> ims_values2(num_points);
102
  std::vector<double> ims_values3(num_points);
103
 
104
- // Generate z values from 0 to 10 (or adjust range as needed)
105
  double z_start = 0.01; // Avoid z=0 to prevent potential division issues
106
  double z_end = 10.0;
107
  double z_step = (z_end - z_start) / (num_points - 1);
@@ -135,13 +150,13 @@ std::vector<std::vector<double>> computeImSVsZ(double a, double y, double beta,
135
  }
136
 
137
  // Function to save Im(s) vs z data as JSON
138
- void saveImSDataAsJSON(const std::string& filename,
139
  const std::vector<std::vector<double>>& data) {
140
  std::ofstream outfile(filename);
141
 
142
  if (!outfile.is_open()) {
143
  std::cerr << "Error: Could not open file " << filename << " for writing." << std::endl;
144
- return;
145
  }
146
 
147
  // Start JSON object
@@ -183,6 +198,7 @@ void saveImSDataAsJSON(const std::string& filename,
183
  outfile << "}\n";
184
 
185
  outfile.close();
 
186
  }
187
 
188
  // Function to compute the theoretical max value
@@ -283,7 +299,7 @@ double compute_theoretical_min(double a, double y, double beta, int grid_points,
283
  }
284
 
285
  // Function to save data as JSON
286
- void save_as_json(const std::string& filename,
287
  const std::vector<double>& beta_values,
288
  const std::vector<double>& max_eigenvalues,
289
  const std::vector<double>& min_eigenvalues,
@@ -294,7 +310,7 @@ void save_as_json(const std::string& filename,
294
 
295
  if (!outfile.is_open()) {
296
  std::cerr << "Error: Could not open file " << filename << " for writing." << std::endl;
297
- return;
298
  }
299
 
300
  // Start JSON object
@@ -344,12 +360,13 @@ void save_as_json(const std::string& filename,
344
  outfile << "}\n";
345
 
346
  outfile.close();
 
347
  }
348
 
349
  // Eigenvalue analysis function
350
- void eigenvalueAnalysis(int n, int p, double a, double y, int fineness,
351
- int theory_grid_points, double theory_tolerance,
352
- const std::string& output_file) {
353
 
354
  std::cout << "Running eigenvalue analysis with parameters: n = " << n << ", p = " << p
355
  << ", a = " << a << ", y = " << y << ", fineness = " << fineness
@@ -370,78 +387,105 @@ void eigenvalueAnalysis(int n, int p, double a, double y, int fineness,
370
  std::vector<double> theoretical_max_values(num_beta_points);
371
  std::vector<double> theoretical_min_values(num_beta_points);
372
 
373
- // ─── Random‐Gaussian X and S_n ────────────────────────────────
374
- std::mt19937_64 rng{std::random_device{}()};
375
- std::normal_distribution<double> norm(0.0, 1.0);
376
-
377
- cv::Mat X(p, n, CV_64F);
378
- for(int i = 0; i < p; ++i)
379
- for(int j = 0; j < n; ++j)
380
- X.at<double>(i,j) = norm(rng);
381
-
382
- // ─── Process each beta value ─────────────────────────────────
383
- for (int beta_idx = 0; beta_idx < num_beta_points; ++beta_idx) {
384
- double beta = beta_values[beta_idx];
385
 
386
- // Compute theoretical values with customizable precision
387
- theoretical_max_values[beta_idx] = compute_theoretical_max(a, y, beta, theory_grid_points, theory_tolerance);
388
- theoretical_min_values[beta_idx] = compute_theoretical_min(a, y, beta, theory_grid_points, theory_tolerance);
 
389
 
390
- // ─── Build T_n matrix ──────────────────────────────────
391
- int k = static_cast<int>(std::floor(beta * p));
392
- std::vector<double> diags(p, 1.0);
393
- std::fill_n(diags.begin(), k, a);
394
- std::shuffle(diags.begin(), diags.end(), rng);
395
-
396
- cv::Mat T_n = cv::Mat::zeros(p, p, CV_64F);
397
- for(int i = 0; i < p; ++i){
398
- T_n.at<double>(i,i) = diags[i];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  }
400
 
401
- // ─── Form B_n = (1/n) * X * T_n * X^T ────────────
402
- cv::Mat B = (X.t() * T_n * X) / static_cast<double>(n);
403
-
404
- // ─── Compute eigenvalues of B ────────────────────────────
405
- cv::Mat eigVals;
406
- cv::eigen(B, eigVals);
407
- std::vector<double> eigs(n);
408
- for(int i = 0; i < n; ++i)
409
- eigs[i] = eigVals.at<double>(i, 0);
410
-
411
- max_eigenvalues[beta_idx] = *std::max_element(eigs.begin(), eigs.end());
412
- min_eigenvalues[beta_idx] = *std::min_element(eigs.begin(), eigs.end());
413
-
414
- // Progress indicator for Streamlit
415
- double progress = static_cast<double>(beta_idx + 1) / num_beta_points;
416
- std::cout << "PROGRESS:" << progress << std::endl;
417
-
418
- // Less verbose output for Streamlit
419
- if (beta_idx % 20 == 0 || beta_idx == num_beta_points - 1) {
420
- std::cout << "Processing beta = " << beta
421
- << " (" << beta_idx+1 << "/" << num_beta_points << ")" << std::endl;
422
  }
 
 
 
 
 
 
 
 
 
 
 
423
  }
424
-
425
- // Save data as JSON for Python to read
426
- save_as_json(output_file, beta_values, max_eigenvalues, min_eigenvalues,
427
- theoretical_max_values, theoretical_min_values);
428
-
429
- std::cout << "Data saved to " << output_file << std::endl;
430
  }
431
 
432
  // Cubic equation analysis function
433
- void cubicAnalysis(double a, double y, double beta, int num_points, const std::string& output_file) {
434
  std::cout << "Running cubic equation analysis with parameters: a = " << a
435
  << ", y = " << y << ", beta = " << beta << ", num_points = " << num_points << std::endl;
436
  std::cout << "Output will be saved to: " << output_file << std::endl;
437
 
438
- // Compute Im(s) vs z data
439
- std::vector<std::vector<double>> ims_data = computeImSVsZ(a, y, beta, num_points);
440
-
441
- // Save to JSON
442
- saveImSDataAsJSON(output_file, ims_data);
443
-
444
- std::cout << "Cubic equation data saved to " << output_file << std::endl;
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  }
446
 
447
  int main(int argc, char* argv[]) {
@@ -461,46 +505,56 @@ int main(int argc, char* argv[]) {
461
 
462
  std::string mode = argv[1];
463
 
464
- if (mode == "eigenvalues") {
465
- // ─── Eigenvalue analysis mode ───────────────────────────────────────────
466
- if (argc != 10) {
467
- std::cerr << "Error: Incorrect number of arguments for eigenvalues mode." << std::endl;
468
- std::cerr << "Usage: " << argv[0] << " eigenvalues <n> <p> <a> <y> <fineness> <theory_grid_points> <theory_tolerance> <output_file>" << std::endl;
469
- std::cerr << "Received " << argc << " arguments, expected 10." << std::endl;
470
- return 1;
471
- }
472
-
473
- int n = std::stoi(argv[2]);
474
- int p = std::stoi(argv[3]);
475
- double a = std::stod(argv[4]);
476
- double y = std::stod(argv[5]);
477
- int fineness = std::stoi(argv[6]);
478
- int theory_grid_points = std::stoi(argv[7]);
479
- double theory_tolerance = std::stod(argv[8]);
480
- std::string output_file = argv[9];
481
-
482
- eigenvalueAnalysis(n, p, a, y, fineness, theory_grid_points, theory_tolerance, output_file);
483
-
484
- } else if (mode == "cubic") {
485
- // ─── Cubic equation analysis mode ───────────────────────────────────────────
486
- if (argc != 7) {
487
- std::cerr << "Error: Incorrect number of arguments for cubic mode." << std::endl;
488
- std::cerr << "Usage: " << argv[0] << " cubic <a> <y> <beta> <num_points> <output_file>" << std::endl;
489
- std::cerr << "Received " << argc << " arguments, expected 7." << std::endl;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490
  return 1;
491
  }
492
-
493
- double a = std::stod(argv[2]);
494
- double y = std::stod(argv[3]);
495
- double beta = std::stod(argv[4]);
496
- int num_points = std::stoi(argv[5]);
497
- std::string output_file = argv[6];
498
-
499
- cubicAnalysis(a, y, beta, num_points, output_file);
500
-
501
- } else {
502
- std::cerr << "Error: Unknown mode: " << mode << std::endl;
503
- std::cerr << "Use 'eigenvalues' or 'cubic'" << std::endl;
504
  return 1;
505
  }
506
 
 
1
+ // app.cpp - Modified version for command line arguments with improvements
2
  #include <opencv2/opencv.hpp>
3
  #include <algorithm>
4
  #include <cmath>
 
12
  #include <string>
13
  #include <fstream>
14
  #include <complex>
15
+ #include <stdexcept>
16
 
17
  // Struct to hold cubic equation roots
18
  struct CubicRoots {
 
24
  // Function to solve cubic equation: az^3 + bz^2 + cz + d = 0
25
  CubicRoots solveCubic(double a, double b, double c, double d) {
26
  // Handle special case for a == 0 (quadratic)
27
+ const double epsilon = 1e-14;
28
+ if (std::abs(a) < epsilon) {
29
  CubicRoots roots;
30
  // For a quadratic equation: bz^2 + cz + d = 0
31
+ if (std::abs(b) < epsilon) { // Linear equation or constant
32
+ if (std::abs(c) < epsilon) { // Constant - no finite roots
33
+ roots.root1 = std::complex<double>(std::numeric_limits<double>::quiet_NaN(), 0.0);
34
+ roots.root2 = std::complex<double>(std::numeric_limits<double>::quiet_NaN(), 0.0);
35
+ roots.root3 = std::complex<double>(std::numeric_limits<double>::quiet_NaN(), 0.0);
36
+ } else { // Linear equation
37
+ roots.root1 = std::complex<double>(-d / c, 0.0);
38
+ roots.root2 = std::complex<double>(std::numeric_limits<double>::infinity(), 0.0);
39
+ roots.root3 = std::complex<double>(std::numeric_limits<double>::infinity(), 0.0);
40
+ }
41
+ return roots;
42
+ }
43
+
44
  double discriminant = c * c - 4.0 * b * d;
45
  if (discriminant >= 0) {
46
  double sqrtDiscriminant = std::sqrt(discriminant);
47
  roots.root1 = std::complex<double>((-c + sqrtDiscriminant) / (2.0 * b), 0.0);
48
  roots.root2 = std::complex<double>((-c - sqrtDiscriminant) / (2.0 * b), 0.0);
49
+ roots.root3 = std::complex<double>(std::numeric_limits<double>::infinity(), 0.0);
50
  } else {
51
  double real = -c / (2.0 * b);
52
  double imag = std::sqrt(-discriminant) / (2.0 * b);
53
  roots.root1 = std::complex<double>(real, imag);
54
  roots.root2 = std::complex<double>(real, -imag);
55
+ roots.root3 = std::complex<double>(std::numeric_limits<double>::infinity(), 0.0);
56
  }
57
  return roots;
58
  }
 
76
 
77
  CubicRoots roots;
78
 
79
+ if (D > epsilon) { // One real root and two complex conjugate roots
80
  double sqrtD = std::sqrt(D);
81
  double u = std::cbrt(-q1 / 2.0 + sqrtD);
82
  double v = std::cbrt(-q1 / 2.0 - sqrtD);
 
90
  roots.root2 = std::complex<double>(real_part, imag_part);
91
  roots.root3 = std::complex<double>(real_part, -imag_part);
92
  }
93
+ else if (D < -epsilon) { // Three distinct real roots
94
  double angle = std::acos(-q1 / 2.0 * std::sqrt(-27.0 / (p1 * p1 * p1)));
95
  double magnitude = 2.0 * std::sqrt(-p1 / 3.0);
96
 
 
116
  std::vector<double> ims_values2(num_points);
117
  std::vector<double> ims_values3(num_points);
118
 
119
+ // Generate z values from 0.01 to 10 (or adjust range as needed)
120
  double z_start = 0.01; // Avoid z=0 to prevent potential division issues
121
  double z_end = 10.0;
122
  double z_step = (z_end - z_start) / (num_points - 1);
 
150
  }
151
 
152
  // Function to save Im(s) vs z data as JSON
153
+ bool saveImSDataAsJSON(const std::string& filename,
154
  const std::vector<std::vector<double>>& data) {
155
  std::ofstream outfile(filename);
156
 
157
  if (!outfile.is_open()) {
158
  std::cerr << "Error: Could not open file " << filename << " for writing." << std::endl;
159
+ return false;
160
  }
161
 
162
  // Start JSON object
 
198
  outfile << "}\n";
199
 
200
  outfile.close();
201
+ return true;
202
  }
203
 
204
  // Function to compute the theoretical max value
 
299
  }
300
 
301
  // Function to save data as JSON
302
+ bool save_as_json(const std::string& filename,
303
  const std::vector<double>& beta_values,
304
  const std::vector<double>& max_eigenvalues,
305
  const std::vector<double>& min_eigenvalues,
 
310
 
311
  if (!outfile.is_open()) {
312
  std::cerr << "Error: Could not open file " << filename << " for writing." << std::endl;
313
+ return false;
314
  }
315
 
316
  // Start JSON object
 
360
  outfile << "}\n";
361
 
362
  outfile.close();
363
+ return true;
364
  }
365
 
366
  // Eigenvalue analysis function
367
+ bool eigenvalueAnalysis(int n, int p, double a, double y, int fineness,
368
+ int theory_grid_points, double theory_tolerance,
369
+ const std::string& output_file) {
370
 
371
  std::cout << "Running eigenvalue analysis with parameters: n = " << n << ", p = " << p
372
  << ", a = " << a << ", y = " << y << ", fineness = " << fineness
 
387
  std::vector<double> theoretical_max_values(num_beta_points);
388
  std::vector<double> theoretical_min_values(num_beta_points);
389
 
390
+ try {
391
+ // ─── Random‐Gaussian X and S_n ────────────────────────────────
392
+ std::random_device rd;
393
+ std::mt19937_64 rng{rd()};
394
+ std::normal_distribution<double> norm(0.0, 1.0);
 
 
 
 
 
 
 
395
 
396
+ cv::Mat X(p, n, CV_64F);
397
+ for(int i = 0; i < p; ++i)
398
+ for(int j = 0; j < n; ++j)
399
+ X.at<double>(i,j) = norm(rng);
400
 
401
+ // ─── Process each beta value ─────────────────────────────────
402
+ for (int beta_idx = 0; beta_idx < num_beta_points; ++beta_idx) {
403
+ double beta = beta_values[beta_idx];
404
+
405
+ // Compute theoretical values with customizable precision
406
+ theoretical_max_values[beta_idx] = compute_theoretical_max(a, y, beta, theory_grid_points, theory_tolerance);
407
+ theoretical_min_values[beta_idx] = compute_theoretical_min(a, y, beta, theory_grid_points, theory_tolerance);
408
+
409
+ // ─── Build T_n matrix ──────────────────────────────────
410
+ int k = static_cast<int>(std::floor(beta * p));
411
+ std::vector<double> diags(p, 1.0);
412
+ std::fill_n(diags.begin(), k, a);
413
+ std::shuffle(diags.begin(), diags.end(), rng);
414
+
415
+ cv::Mat T_n = cv::Mat::zeros(p, p, CV_64F);
416
+ for(int i = 0; i < p; ++i){
417
+ T_n.at<double>(i,i) = diags[i];
418
+ }
419
+
420
+ // ─── Form B_n = (1/n) * X * T_n * X^T ────────────
421
+ cv::Mat B = (X.t() * T_n * X) / static_cast<double>(n);
422
+
423
+ // ─── Compute eigenvalues of B ────────────────────────────
424
+ cv::Mat eigVals;
425
+ cv::eigen(B, eigVals);
426
+ std::vector<double> eigs(n);
427
+ for(int i = 0; i < n; ++i)
428
+ eigs[i] = eigVals.at<double>(i, 0);
429
+
430
+ max_eigenvalues[beta_idx] = *std::max_element(eigs.begin(), eigs.end());
431
+ min_eigenvalues[beta_idx] = *std::min_element(eigs.begin(), eigs.end());
432
+
433
+ // Progress indicator for Streamlit
434
+ double progress = static_cast<double>(beta_idx + 1) / num_beta_points;
435
+ std::cout << "PROGRESS:" << progress << std::endl;
436
+
437
+ // Less verbose output for Streamlit
438
+ if (beta_idx % 20 == 0 || beta_idx == num_beta_points - 1) {
439
+ std::cout << "Processing beta = " << beta
440
+ << " (" << beta_idx+1 << "/" << num_beta_points << ")" << std::endl;
441
+ }
442
  }
443
 
444
+ // Save data as JSON for Python to read
445
+ if (!save_as_json(output_file, beta_values, max_eigenvalues, min_eigenvalues,
446
+ theoretical_max_values, theoretical_min_values)) {
447
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
448
  }
449
+
450
+ std::cout << "Data saved to " << output_file << std::endl;
451
+ return true;
452
+ }
453
+ catch (const std::exception& e) {
454
+ std::cerr << "Error in eigenvalue analysis: " << e.what() << std::endl;
455
+ return false;
456
+ }
457
+ catch (...) {
458
+ std::cerr << "Unknown error in eigenvalue analysis" << std::endl;
459
+ return false;
460
  }
 
 
 
 
 
 
461
  }
462
 
463
  // Cubic equation analysis function
464
+ bool cubicAnalysis(double a, double y, double beta, int num_points, const std::string& output_file) {
465
  std::cout << "Running cubic equation analysis with parameters: a = " << a
466
  << ", y = " << y << ", beta = " << beta << ", num_points = " << num_points << std::endl;
467
  std::cout << "Output will be saved to: " << output_file << std::endl;
468
 
469
+ try {
470
+ // Compute Im(s) vs z data
471
+ std::vector<std::vector<double>> ims_data = computeImSVsZ(a, y, beta, num_points);
472
+
473
+ // Save to JSON
474
+ if (!saveImSDataAsJSON(output_file, ims_data)) {
475
+ return false;
476
+ }
477
+
478
+ std::cout << "Cubic equation data saved to " << output_file << std::endl;
479
+ return true;
480
+ }
481
+ catch (const std::exception& e) {
482
+ std::cerr << "Error in cubic analysis: " << e.what() << std::endl;
483
+ return false;
484
+ }
485
+ catch (...) {
486
+ std::cerr << "Unknown error in cubic analysis" << std::endl;
487
+ return false;
488
+ }
489
  }
490
 
491
  int main(int argc, char* argv[]) {
 
505
 
506
  std::string mode = argv[1];
507
 
508
+ try {
509
+ if (mode == "eigenvalues") {
510
+ // ─── Eigenvalue analysis mode ───────────────────────────────────────────
511
+ if (argc != 10) {
512
+ std::cerr << "Error: Incorrect number of arguments for eigenvalues mode." << std::endl;
513
+ std::cerr << "Usage: " << argv[0] << " eigenvalues <n> <p> <a> <y> <fineness> <theory_grid_points> <theory_tolerance> <output_file>" << std::endl;
514
+ std::cerr << "Received " << argc << " arguments, expected 10." << std::endl;
515
+ return 1;
516
+ }
517
+
518
+ int n = std::stoi(argv[2]);
519
+ int p = std::stoi(argv[3]);
520
+ double a = std::stod(argv[4]);
521
+ double y = std::stod(argv[5]);
522
+ int fineness = std::stoi(argv[6]);
523
+ int theory_grid_points = std::stoi(argv[7]);
524
+ double theory_tolerance = std::stod(argv[8]);
525
+ std::string output_file = argv[9];
526
+
527
+ if (!eigenvalueAnalysis(n, p, a, y, fineness, theory_grid_points, theory_tolerance, output_file)) {
528
+ return 1;
529
+ }
530
+
531
+ } else if (mode == "cubic") {
532
+ // ─── Cubic equation analysis mode ───────────────────────────────────────────
533
+ if (argc != 7) {
534
+ std::cerr << "Error: Incorrect number of arguments for cubic mode." << std::endl;
535
+ std::cerr << "Usage: " << argv[0] << " cubic <a> <y> <beta> <num_points> <output_file>" << std::endl;
536
+ std::cerr << "Received " << argc << " arguments, expected 7." << std::endl;
537
+ return 1;
538
+ }
539
+
540
+ double a = std::stod(argv[2]);
541
+ double y = std::stod(argv[3]);
542
+ double beta = std::stod(argv[4]);
543
+ int num_points = std::stoi(argv[5]);
544
+ std::string output_file = argv[6];
545
+
546
+ if (!cubicAnalysis(a, y, beta, num_points, output_file)) {
547
+ return 1;
548
+ }
549
+
550
+ } else {
551
+ std::cerr << "Error: Unknown mode: " << mode << std::endl;
552
+ std::cerr << "Use 'eigenvalues' or 'cubic'" << std::endl;
553
  return 1;
554
  }
555
+ }
556
+ catch (const std::exception& e) {
557
+ std::cerr << "Error: " << e.what() << std::endl;
 
 
 
 
 
 
 
 
 
558
  return 1;
559
  }
560