Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -14,30 +14,12 @@ st.set_page_config(
|
|
14 |
layout="wide",
|
15 |
initial_sidebar_state="collapsed"
|
16 |
)
|
17 |
-
# Add at the beginning of app.py, before the import attempt
|
18 |
-
import os
|
19 |
-
import sys
|
20 |
-
|
21 |
-
# Try to find the module in common locations
|
22 |
-
module_locations = [
|
23 |
-
os.getcwd(),
|
24 |
-
os.path.dirname(os.path.abspath(__file__)),
|
25 |
-
'/home/user/app',
|
26 |
-
'/home/user/a'
|
27 |
-
]
|
28 |
|
29 |
-
for loc in module_locations:
|
30 |
-
if loc not in sys.path:
|
31 |
-
sys.path.insert(0, loc)
|
32 |
-
|
33 |
-
# Check for the module file
|
34 |
-
for ext in ['.so', '.cpython-310-x86_64-linux-gnu.so', '.cpython-310-aarch64-linux-gnu.so']:
|
35 |
-
if os.path.exists(os.path.join(loc, f'cubic_cpp{ext}')):
|
36 |
-
print(f"Found module at: {os.path.join(loc, f'cubic_cpp{ext}')}")
|
37 |
# Try to import C++ module
|
38 |
try:
|
39 |
import cubic_cpp
|
40 |
cpp_available = True
|
|
|
41 |
print(f"Loaded C++ module from: {cubic_cpp.__file__}")
|
42 |
except ImportError as e:
|
43 |
print(f"C++ acceleration unavailable: {e}")
|
@@ -47,8 +29,6 @@ except ImportError as e:
|
|
47 |
# Try to compile the module on the fly
|
48 |
try:
|
49 |
import subprocess
|
50 |
-
import sys
|
51 |
-
import os
|
52 |
|
53 |
print("Attempting to compile C++ module at runtime...")
|
54 |
|
@@ -56,7 +36,7 @@ except ImportError as e:
|
|
56 |
ext_suffix = subprocess.check_output("python3-config --extension-suffix", shell=True).decode().strip()
|
57 |
print(f"Extension suffix: {ext_suffix}")
|
58 |
|
59 |
-
# Compile command
|
60 |
compile_cmd = f"""g++ -O3 -shared -std=c++17 -fPIC \
|
61 |
$(python3-config --includes) \
|
62 |
-I$(python3 -c "import pybind11; print(pybind11.get_include())") \
|
@@ -253,11 +233,15 @@ def compute_eigenvalue_support_boundaries_py(z_a, y, beta_values, n_samples=100,
|
|
253 |
@st.cache_data
|
254 |
def compute_cubic_roots_py(z, beta, z_a, y):
|
255 |
"""
|
256 |
-
Compute the roots of the cubic equation for given parameters
|
|
|
257 |
"""
|
258 |
# Apply the condition for y
|
259 |
y_effective = y if y > 1 else 1/y
|
260 |
|
|
|
|
|
|
|
261 |
# Coefficients in the form as^3 + bs^2 + cs + d = 0
|
262 |
a = z * z_a
|
263 |
b = z * z_a + z + z_a - z_a*y_effective
|
@@ -273,9 +257,24 @@ def compute_cubic_roots_py(z, beta, z_a, y):
|
|
273 |
roots = np.append(quad_roots, 0).astype(complex)
|
274 |
return roots
|
275 |
|
276 |
-
#
|
277 |
-
|
278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
|
280 |
@st.cache_data
|
281 |
def compute_high_y_curve_py(betas, z_a, y):
|
@@ -712,14 +711,35 @@ def generate_cubic_discriminant(z, beta, z_a, y_effective):
|
|
712 |
For a cubic ax^3 + bx^2 + cx + d:
|
713 |
Δ = 18abcd - 27a^2d^2 + b^2c^2 - 2b^3d - 9ac^3
|
714 |
"""
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
723 |
|
724 |
def generate_root_plots(beta, y, z_a, z_min, z_max, n_points):
|
725 |
"""
|
@@ -747,14 +767,14 @@ def generate_root_plots(beta, y, z_a, z_min, z_max, n_points):
|
|
747 |
progress_bar.progress((i + 1) / n_points)
|
748 |
status_text.text(f"Computing roots for z = {z:.3f} ({i+1}/{n_points})")
|
749 |
|
750 |
-
# Calculate roots
|
751 |
roots = compute_cubic_roots(z, beta, z_a, y)
|
752 |
|
753 |
# Initial sorting to help with tracking
|
754 |
roots = sorted(roots, key=lambda x: (abs(x.imag), x.real))
|
755 |
all_roots.append(roots)
|
756 |
|
757 |
-
# Calculate discriminant
|
758 |
disc = generate_cubic_discriminant(z, beta, z_a, y_effective)
|
759 |
discriminants.append(disc)
|
760 |
|
@@ -839,14 +859,14 @@ def generate_roots_vs_beta_plots(z, y, z_a, beta_min, beta_max, n_points):
|
|
839 |
progress_bar.progress((i + 1) / n_points)
|
840 |
status_text.text(f"Computing roots for β = {beta:.3f} ({i+1}/{n_points})")
|
841 |
|
842 |
-
# Calculate roots
|
843 |
roots = compute_cubic_roots(z, beta, z_a, y)
|
844 |
|
845 |
# Initial sorting to help with tracking
|
846 |
roots = sorted(roots, key=lambda x: (abs(x.imag), x.real))
|
847 |
all_roots.append(roots)
|
848 |
|
849 |
-
# Calculate discriminant
|
850 |
disc = generate_cubic_discriminant(z, beta, z_a, y_effective)
|
851 |
discriminants.append(disc)
|
852 |
|
|
|
14 |
layout="wide",
|
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}")
|
|
|
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 |
|
|
|
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())") \
|
|
|
233 |
@st.cache_data
|
234 |
def compute_cubic_roots_py(z, beta, z_a, y):
|
235 |
"""
|
236 |
+
Compute the roots of the cubic equation for given parameters using SymPy
|
237 |
+
for enhanced precision.
|
238 |
"""
|
239 |
# Apply the condition for y
|
240 |
y_effective = y if y > 1 else 1/y
|
241 |
|
242 |
+
# Use SymPy for symbolic calculations
|
243 |
+
s = sp.symbols('s')
|
244 |
+
|
245 |
# Coefficients in the form as^3 + bs^2 + cs + d = 0
|
246 |
a = z * z_a
|
247 |
b = z * z_a + z + z_a - z_a*y_effective
|
|
|
257 |
roots = np.append(quad_roots, 0).astype(complex)
|
258 |
return roots
|
259 |
|
260 |
+
# Create the cubic polynomial and solve symbolically
|
261 |
+
cubic_poly = a*s**3 + b*s**2 + c*s + d
|
262 |
+
|
263 |
+
try:
|
264 |
+
# Use SymPy's solve function for high precision
|
265 |
+
symbolic_roots = sp.solve(cubic_poly, s)
|
266 |
+
# Convert to complex numpy array
|
267 |
+
roots = np.array([complex(root.evalf()) for root in symbolic_roots], dtype=complex)
|
268 |
+
|
269 |
+
# Ensure we have exactly 3 roots (SymPy might return fewer for multiple roots)
|
270 |
+
if len(roots) < 3:
|
271 |
+
# Fill in duplicates for multiple roots
|
272 |
+
roots = np.append(roots, np.full(3 - len(roots), roots[-1]))
|
273 |
+
|
274 |
+
return roots
|
275 |
+
except Exception:
|
276 |
+
# Fall back to numpy if SymPy fails
|
277 |
+
return np.roots([a, b, c, d])
|
278 |
|
279 |
@st.cache_data
|
280 |
def compute_high_y_curve_py(betas, z_a, y):
|
|
|
711 |
For a cubic ax^3 + bx^2 + cx + d:
|
712 |
Δ = 18abcd - 27a^2d^2 + b^2c^2 - 2b^3d - 9ac^3
|
713 |
"""
|
714 |
+
# Use SymPy for more accurate computation when possible
|
715 |
+
try:
|
716 |
+
# Convert to sympy expressions for high precision
|
717 |
+
z_sym = sp.Rational(str(z))
|
718 |
+
beta_sym = sp.Rational(str(beta))
|
719 |
+
z_a_sym = sp.Rational(str(z_a))
|
720 |
+
y_sym = sp.Rational(str(y_effective))
|
721 |
+
|
722 |
+
# Define coefficients symbolically
|
723 |
+
a_sym = z_sym * z_a_sym
|
724 |
+
b_sym = z_sym * z_a_sym + z_sym + z_a_sym - z_a_sym*y_sym
|
725 |
+
c_sym = z_sym + z_a_sym + 1 - y_sym*(beta_sym*z_a_sym + 1 - beta_sym)
|
726 |
+
d_sym = 1
|
727 |
+
|
728 |
+
# Standard formula for cubic discriminant
|
729 |
+
discriminant = (18*a_sym*b_sym*c_sym*d_sym - 27*a_sym**2*d_sym**2 +
|
730 |
+
b_sym**2*c_sym**2 - 2*b_sym**3*d_sym - 9*a_sym*c_sym**3)
|
731 |
+
|
732 |
+
return float(discriminant.evalf())
|
733 |
+
except Exception:
|
734 |
+
# Fall back to numeric computation if SymPy fails
|
735 |
+
a = z * z_a
|
736 |
+
b = z * z_a + z + z_a - z_a*y_effective
|
737 |
+
c = z + z_a + 1 - y_effective*(beta*z_a + 1 - beta)
|
738 |
+
d = 1
|
739 |
+
|
740 |
+
# Standard formula for cubic discriminant
|
741 |
+
discriminant = (18*a*b*c*d - 27*a**2*d**2 + b**2*c**2 - 2*b**3*d - 9*a*c**3)
|
742 |
+
return discriminant
|
743 |
|
744 |
def generate_root_plots(beta, y, z_a, z_min, z_max, n_points):
|
745 |
"""
|
|
|
767 |
progress_bar.progress((i + 1) / n_points)
|
768 |
status_text.text(f"Computing roots for z = {z:.3f} ({i+1}/{n_points})")
|
769 |
|
770 |
+
# Calculate roots with SymPy for higher precision
|
771 |
roots = compute_cubic_roots(z, beta, z_a, y)
|
772 |
|
773 |
# Initial sorting to help with tracking
|
774 |
roots = sorted(roots, key=lambda x: (abs(x.imag), x.real))
|
775 |
all_roots.append(roots)
|
776 |
|
777 |
+
# Calculate discriminant with SymPy for higher precision
|
778 |
disc = generate_cubic_discriminant(z, beta, z_a, y_effective)
|
779 |
discriminants.append(disc)
|
780 |
|
|
|
859 |
progress_bar.progress((i + 1) / n_points)
|
860 |
status_text.text(f"Computing roots for β = {beta:.3f} ({i+1}/{n_points})")
|
861 |
|
862 |
+
# Calculate roots with SymPy for higher precision
|
863 |
roots = compute_cubic_roots(z, beta, z_a, y)
|
864 |
|
865 |
# Initial sorting to help with tracking
|
866 |
roots = sorted(roots, key=lambda x: (abs(x.imag), x.real))
|
867 |
all_roots.append(roots)
|
868 |
|
869 |
+
# Calculate discriminant with SymPy for higher precision
|
870 |
disc = generate_cubic_discriminant(z, beta, z_a, y_effective)
|
871 |
discriminants.append(disc)
|
872 |
|