euler314 commited on
Commit
42690e4
·
verified ·
1 Parent(s): 9d5e862

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -121
app.py CHANGED
@@ -7,6 +7,7 @@ from scipy.stats import gaussian_kde
7
  import sys
8
  import os
9
  import importlib.util
 
10
 
11
  # Configure Streamlit for Hugging Face Spaces - THIS MUST COME FIRST
12
  st.set_page_config(
@@ -15,28 +16,15 @@ st.set_page_config(
15
  initial_sidebar_state="collapsed"
16
  )
17
 
18
- # Try to import C++ module
19
- try:
20
- import cubic_cpp
21
- cpp_available = True
22
- # Print the location of the imported module to verify
23
- print(f"Loaded C++ module from: {cubic_cpp.__file__}")
24
- except ImportError as e:
25
- print(f"C++ acceleration unavailable: {e}")
26
- print(f"Python path: {sys.path}")
27
- print(f"Current directory: {os.getcwd()}")
28
-
29
- # Try to compile the module on the fly
30
  try:
31
- import subprocess
32
-
33
- print("Attempting to compile C++ module at runtime...")
34
-
35
- # Get the extension suffix for this Python version
36
  ext_suffix = subprocess.check_output("python3-config --extension-suffix", shell=True).decode().strip()
37
  print(f"Extension suffix: {ext_suffix}")
38
 
39
- # Compile command with C++17
40
  compile_cmd = f"""g++ -O3 -shared -std=c++17 -fPIC \
41
  $(python3-config --includes) \
42
  -I$(python3 -c "import pybind11; print(pybind11.get_include())") \
@@ -49,23 +37,39 @@ except ImportError as e:
49
 
50
  if result.returncode == 0:
51
  print("Compilation successful")
52
- # Try to import again
53
- sys.path.insert(0, os.getcwd()) # Ensure current directory is in path
54
- import importlib.util
55
- spec = importlib.util.spec_from_file_location("cubic_cpp", os.path.join(os.getcwd(), "cubic_cpp" + ext_suffix))
 
56
  if spec:
57
  cubic_cpp = importlib.util.module_from_spec(spec)
58
  spec.loader.exec_module(cubic_cpp)
59
- cpp_available = True
60
  print(f"Successfully imported compiled module")
61
- else:
62
- raise ImportError(f"Failed to load module spec for cubic_cpp")
63
  else:
64
  print(f"Compilation failed: {result.stderr}")
65
- raise RuntimeError(f"C++ compilation failed: {result.stderr}")
66
- except Exception as compile_error:
67
- print(f"Failed to compile C++ module: {compile_error}")
68
- cpp_available = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  def add_sqrt_support(expr_str):
71
  """Replace 'sqrt(' with 'sp.sqrt(' for sympy compatibility"""
@@ -90,8 +94,7 @@ Delta_expr = (
90
  + (c_sym/(3*a_sym) - (b_sym**2)/(9*a_sym**2))**3
91
  )
92
 
93
- # Define fallback Python implementations for all functions
94
- # These will be used if C++ module is unavailable
95
 
96
  def discriminant_func_py(z, beta, z_a, y):
97
  """Fast numeric function for the discriminant"""
@@ -411,20 +414,30 @@ def generate_eigenvalue_distribution_py(beta, y, z_a, n=1000, seed=42):
411
  eigenvalues = np.linalg.eigvalsh(B_n)
412
  return eigenvalues
413
 
414
- # Use C++ implementations if available, otherwise use Python implementations
415
  if cpp_available:
416
- discriminant_func = cubic_cpp.discriminant_func
417
- find_z_at_discriminant_zero = cubic_cpp.find_z_at_discriminant_zero
418
- sweep_beta_and_find_z_bounds = cubic_cpp.sweep_beta_and_find_z_bounds
419
- compute_eigenvalue_support_boundaries = cubic_cpp.compute_eigenvalue_support_boundaries
420
- compute_cubic_roots = cubic_cpp.compute_cubic_roots
421
- compute_high_y_curve = cubic_cpp.compute_high_y_curve
422
- compute_alternate_low_expr = cubic_cpp.compute_alternate_low_expr
423
- compute_max_k_expression = cubic_cpp.compute_max_k_expression
424
- compute_min_t_expression = cubic_cpp.compute_min_t_expression
425
- compute_derivatives = cubic_cpp.compute_derivatives
426
- generate_eigenvalue_distribution = lambda beta, y, z_a, n=1000, seed=42: cubic_cpp.generate_eigenvalue_distribution(beta, y, z_a, n, seed)
 
 
 
 
 
 
 
 
 
427
  else:
 
428
  discriminant_func = discriminant_func_py
429
  find_z_at_discriminant_zero = find_z_at_discriminant_zero_py
430
  sweep_beta_and_find_z_bounds = sweep_beta_and_find_z_bounds_py
@@ -1057,84 +1070,7 @@ def generate_eigenvalue_distribution_plot(beta, y, z_a, n=1000, seed=42):
1057
  )
1058
 
1059
  return fig, eigenvalues
1060
- # Use C++ implementations if available, otherwise use Python implementations
1061
- if cpp_available:
1062
- # First check which functions actually exist in the C++ module
1063
- available_cpp_functions = []
1064
- for func_name in dir(cubic_cpp):
1065
- if not func_name.startswith('_'):
1066
- available_cpp_functions.append(func_name)
1067
-
1068
- print(f"Available C++ functions: {available_cpp_functions}")
1069
-
1070
- # Now assign functions based on what's available
1071
- if "discriminant_func" in available_cpp_functions:
1072
- discriminant_func = cubic_cpp.discriminant_func
1073
- else:
1074
- discriminant_func = discriminant_func_py
1075
-
1076
- if "find_z_at_discriminant_zero" in available_cpp_functions:
1077
- find_z_at_discriminant_zero = cubic_cpp.find_z_at_discriminant_zero
1078
- else:
1079
- find_z_at_discriminant_zero = find_z_at_discriminant_zero_py
1080
-
1081
- if "sweep_beta_and_find_z_bounds" in available_cpp_functions:
1082
- sweep_beta_and_find_z_bounds = cubic_cpp.sweep_beta_and_find_z_bounds
1083
- else:
1084
- sweep_beta_and_find_z_bounds = sweep_beta_and_find_z_bounds_py
1085
-
1086
- if "compute_eigenvalue_support_boundaries" in available_cpp_functions:
1087
- compute_eigenvalue_support_boundaries = cubic_cpp.compute_eigenvalue_support_boundaries
1088
- else:
1089
- compute_eigenvalue_support_boundaries = compute_eigenvalue_support_boundaries_py
1090
-
1091
- if "compute_cubic_roots" in available_cpp_functions:
1092
- compute_cubic_roots = cubic_cpp.compute_cubic_roots
1093
- else:
1094
- compute_cubic_roots = compute_cubic_roots_py
1095
-
1096
- if "compute_high_y_curve" in available_cpp_functions:
1097
- compute_high_y_curve = cubic_cpp.compute_high_y_curve
1098
- else:
1099
- compute_high_y_curve = compute_high_y_curve_py
1100
-
1101
- if "compute_alternate_low_expr" in available_cpp_functions:
1102
- compute_alternate_low_expr = cubic_cpp.compute_alternate_low_expr
1103
- else:
1104
- compute_alternate_low_expr = compute_alternate_low_expr_py
1105
-
1106
- if "compute_max_k_expression" in available_cpp_functions:
1107
- compute_max_k_expression = cubic_cpp.compute_max_k_expression
1108
- else:
1109
- compute_max_k_expression = compute_max_k_expression_py
1110
-
1111
- if "compute_min_t_expression" in available_cpp_functions:
1112
- compute_min_t_expression = cubic_cpp.compute_min_t_expression
1113
- else:
1114
- compute_min_t_expression = compute_min_t_expression_py
1115
-
1116
- if "compute_derivatives" in available_cpp_functions:
1117
- compute_derivatives = cubic_cpp.compute_derivatives
1118
- else:
1119
- compute_derivatives = compute_derivatives_py
1120
-
1121
- if "generate_eigenvalue_distribution" in available_cpp_functions:
1122
- generate_eigenvalue_distribution = lambda beta, y, z_a, n=1000, seed=42: cubic_cpp.generate_eigenvalue_distribution(beta, y, z_a, n, seed)
1123
- else:
1124
- generate_eigenvalue_distribution = generate_eigenvalue_distribution_py
1125
- else:
1126
- # Use all Python implementations
1127
- discriminant_func = discriminant_func_py
1128
- find_z_at_discriminant_zero = find_z_at_discriminant_zero_py
1129
- sweep_beta_and_find_z_bounds = sweep_beta_and_find_z_bounds_py
1130
- compute_eigenvalue_support_boundaries = compute_eigenvalue_support_boundaries_py
1131
- compute_cubic_roots = compute_cubic_roots_py
1132
- compute_high_y_curve = compute_high_y_curve_py
1133
- compute_alternate_low_expr = compute_alternate_low_expr_py
1134
- compute_max_k_expression = compute_max_k_expression_py
1135
- compute_min_t_expression = compute_min_t_expression_py
1136
- compute_derivatives = compute_derivatives_py
1137
- generate_eigenvalue_distribution = generate_eigenvalue_distribution_py
1138
  # ----------------- Streamlit UI -----------------
1139
  def main():
1140
  st.title("Cubic Root Analysis")
 
7
  import sys
8
  import os
9
  import importlib.util
10
+ import subprocess
11
 
12
  # Configure Streamlit for Hugging Face Spaces - THIS MUST COME FIRST
13
  st.set_page_config(
 
16
  initial_sidebar_state="collapsed"
17
  )
18
 
19
+ # Function to dynamically compile the C++ module
20
+ def compile_cpp_module():
 
 
 
 
 
 
 
 
 
 
21
  try:
22
+ print("Attempting to compile C++ module...")
23
+ # Get extension suffix
 
 
 
24
  ext_suffix = subprocess.check_output("python3-config --extension-suffix", shell=True).decode().strip()
25
  print(f"Extension suffix: {ext_suffix}")
26
 
27
+ # Compile command using C++17
28
  compile_cmd = f"""g++ -O3 -shared -std=c++17 -fPIC \
29
  $(python3-config --includes) \
30
  -I$(python3 -c "import pybind11; print(pybind11.get_include())") \
 
37
 
38
  if result.returncode == 0:
39
  print("Compilation successful")
40
+ # Try to import the newly compiled module
41
+ spec = importlib.util.spec_from_file_location(
42
+ "cubic_cpp",
43
+ os.path.join(os.getcwd(), "cubic_cpp" + ext_suffix)
44
+ )
45
  if spec:
46
  cubic_cpp = importlib.util.module_from_spec(spec)
47
  spec.loader.exec_module(cubic_cpp)
 
48
  print(f"Successfully imported compiled module")
49
+ return cubic_cpp
 
50
  else:
51
  print(f"Compilation failed: {result.stderr}")
52
+ except Exception as e:
53
+ print(f"Error during compilation: {e}")
54
+
55
+ return None
56
+
57
+ # Try to import or compile the C++ module
58
+ try:
59
+ import cubic_cpp
60
+ print(f"Loaded existing C++ module from: {cubic_cpp.__file__}")
61
+ cpp_available = True
62
+ except ImportError:
63
+ print("C++ acceleration unavailable: No module named 'cubic_cpp'")
64
+ print(f"Python path: {sys.path}")
65
+ print(f"Current directory: {os.getcwd()}")
66
+
67
+ # Try to compile the module
68
+ cubic_cpp = compile_cpp_module()
69
+ cpp_available = cubic_cpp is not None
70
+
71
+ if cpp_available:
72
+ print(f"Loaded C++ module from: {cubic_cpp.__file__}")
73
 
74
  def add_sqrt_support(expr_str):
75
  """Replace 'sqrt(' with 'sp.sqrt(' for sympy compatibility"""
 
94
  + (c_sym/(3*a_sym) - (b_sym**2)/(9*a_sym**2))**3
95
  )
96
 
97
+ # Define Python implementations for all functions
 
98
 
99
  def discriminant_func_py(z, beta, z_a, y):
100
  """Fast numeric function for the discriminant"""
 
414
  eigenvalues = np.linalg.eigvalsh(B_n)
415
  return eigenvalues
416
 
417
+ # Now determine which functions to use
418
  if cpp_available:
419
+ # Get list of available C++ functions
420
+ cpp_functions = [name for name in dir(cubic_cpp) if not name.startswith('_')]
421
+ print(f"Available C++ functions: {cpp_functions}")
422
+
423
+ # Assign function implementations based on what's available
424
+ discriminant_func = cubic_cpp.discriminant_func if 'discriminant_func' in cpp_functions else discriminant_func_py
425
+ find_z_at_discriminant_zero = cubic_cpp.find_z_at_discriminant_zero if 'find_z_at_discriminant_zero' in cpp_functions else find_z_at_discriminant_zero_py
426
+ sweep_beta_and_find_z_bounds = cubic_cpp.sweep_beta_and_find_z_bounds if 'sweep_beta_and_find_z_bounds' in cpp_functions else sweep_beta_and_find_z_bounds_py
427
+ compute_eigenvalue_support_boundaries = cubic_cpp.compute_eigenvalue_support_boundaries if 'compute_eigenvalue_support_boundaries' in cpp_functions else compute_eigenvalue_support_boundaries_py
428
+ compute_cubic_roots = cubic_cpp.compute_cubic_roots if 'compute_cubic_roots' in cpp_functions else compute_cubic_roots_py
429
+ compute_high_y_curve = cubic_cpp.compute_high_y_curve if 'compute_high_y_curve' in cpp_functions else compute_high_y_curve_py
430
+ compute_alternate_low_expr = cubic_cpp.compute_alternate_low_expr if 'compute_alternate_low_expr' in cpp_functions else compute_alternate_low_expr_py
431
+ compute_max_k_expression = cubic_cpp.compute_max_k_expression if 'compute_max_k_expression' in cpp_functions else compute_max_k_expression_py
432
+ compute_min_t_expression = cubic_cpp.compute_min_t_expression if 'compute_min_t_expression' in cpp_functions else compute_min_t_expression_py
433
+ compute_derivatives = cubic_cpp.compute_derivatives if 'compute_derivatives' in cpp_functions else compute_derivatives_py
434
+
435
+ if 'generate_eigenvalue_distribution' in cpp_functions:
436
+ generate_eigenvalue_distribution = lambda beta, y, z_a, n=1000, seed=42: cubic_cpp.generate_eigenvalue_distribution(beta, y, z_a, n, seed)
437
+ else:
438
+ generate_eigenvalue_distribution = generate_eigenvalue_distribution_py
439
  else:
440
+ # Use all Python implementations
441
  discriminant_func = discriminant_func_py
442
  find_z_at_discriminant_zero = find_z_at_discriminant_zero_py
443
  sweep_beta_and_find_z_bounds = sweep_beta_and_find_z_bounds_py
 
1070
  )
1071
 
1072
  return fig, eigenvalues
1073
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1074
  # ----------------- Streamlit UI -----------------
1075
  def main():
1076
  st.title("Cubic Root Analysis")