Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -90,8 +90,6 @@ def sweep_beta_and_find_z_bounds(z_a, y, z_min, z_max, beta_steps, z_steps):
|
|
90 |
z_max_values.append(np.max(roots))
|
91 |
return betas, np.array(z_min_values), np.array(z_max_values)
|
92 |
|
93 |
-
# Removed the compute_low_y_curve function
|
94 |
-
|
95 |
@st.cache_data
|
96 |
def compute_high_y_curve(betas, z_a, y):
|
97 |
"""
|
@@ -113,6 +111,65 @@ def compute_alternate_low_expr(betas, z_a, y):
|
|
113 |
betas = np.array(betas)
|
114 |
return (z_a * y * betas * (z_a - 1) - 2*z_a*(1 - y) - 2*z_a**2) / (2 + 2*z_a)
|
115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
@st.cache_data
|
117 |
def compute_derivatives(curve, betas):
|
118 |
"""Compute first and second derivatives of a curve"""
|
@@ -202,6 +259,10 @@ def generate_z_vs_beta_plot(z_a, y, z_min, z_max, beta_steps, z_steps,
|
|
202 |
high_y_curve = compute_high_y_curve(betas, z_a, y)
|
203 |
alt_low_expr = compute_alternate_low_expr(betas, z_a, y)
|
204 |
|
|
|
|
|
|
|
|
|
205 |
# Compute both custom curves
|
206 |
custom_curve1 = None
|
207 |
custom_curve2 = None
|
@@ -214,6 +275,9 @@ def generate_z_vs_beta_plot(z_a, y, z_min, z_max, beta_steps, z_steps,
|
|
214 |
if show_derivatives:
|
215 |
derivatives = compute_all_derivatives(betas, z_mins, z_maxs, None, high_y_curve,
|
216 |
alt_low_expr, custom_curve1, custom_curve2)
|
|
|
|
|
|
|
217 |
|
218 |
fig = go.Figure()
|
219 |
|
@@ -228,6 +292,12 @@ def generate_z_vs_beta_plot(z_a, y, z_min, z_max, beta_steps, z_steps,
|
|
228 |
fig.add_trace(go.Scatter(x=betas, y=alt_low_expr, mode="markers+lines",
|
229 |
name="Low Expression", line=dict(color='green')))
|
230 |
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
if custom_curve1 is not None:
|
232 |
fig.add_trace(go.Scatter(x=betas, y=custom_curve1, mode="markers+lines",
|
233 |
name="Custom 1 (s-based)", line=dict(color='purple')))
|
@@ -255,6 +325,16 @@ def generate_z_vs_beta_plot(z_a, y, z_min, z_max, beta_steps, z_steps,
|
|
255 |
name=f"{name} d/dβ", line=dict(color=color, dash='dash')))
|
256 |
fig.add_trace(go.Scatter(x=betas, y=derivatives[key][1], mode="lines",
|
257 |
name=f"{name} d²/dβ²", line=dict(color=color, dash='dot')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
|
259 |
fig.update_layout(
|
260 |
title="Curves vs β: z*(β) Boundaries and Asymptotic Expressions",
|
@@ -428,7 +508,9 @@ with tab1:
|
|
428 |
- **Upper z*(β)** (Blue): Maximum z value where discriminant is zero
|
429 |
- **Lower z*(β)** (Light Blue): Minimum z value where discriminant is zero
|
430 |
- **High y Expression** (Green): Asymptotic approximation for high y values
|
431 |
-
- **Low Expression** (
|
|
|
|
|
432 |
- **Custom Expression 1** (Purple): Result from user-defined s substituted into the main formula
|
433 |
- **Custom Expression 2** (Magenta): Direct z(β) expression
|
434 |
""")
|
|
|
90 |
z_max_values.append(np.max(roots))
|
91 |
return betas, np.array(z_min_values), np.array(z_max_values)
|
92 |
|
|
|
|
|
93 |
@st.cache_data
|
94 |
def compute_high_y_curve(betas, z_a, y):
|
95 |
"""
|
|
|
111 |
betas = np.array(betas)
|
112 |
return (z_a * y * betas * (z_a - 1) - 2*z_a*(1 - y) - 2*z_a**2) / (2 + 2*z_a)
|
113 |
|
114 |
+
@st.cache_data
|
115 |
+
def compute_max_k_expression(betas, z_a, y, k_samples=1000):
|
116 |
+
"""
|
117 |
+
Compute max_{k ∈ (0,∞)} (y*beta*(a-1)*k + (a*k+1)*((y-1)*k-1)) / ((a*k+1)*(k^2+k))
|
118 |
+
"""
|
119 |
+
a = z_a
|
120 |
+
# Sample k values on a logarithmic scale
|
121 |
+
k_values = np.logspace(-3, 3, k_samples)
|
122 |
+
|
123 |
+
max_vals = np.zeros_like(betas)
|
124 |
+
for i, beta in enumerate(betas):
|
125 |
+
values = np.zeros_like(k_values)
|
126 |
+
for j, k in enumerate(k_values):
|
127 |
+
numerator = y*beta*(a-1)*k + (a*k+1)*((y-1)*k-1)
|
128 |
+
denominator = (a*k+1)*(k**2+k)
|
129 |
+
if abs(denominator) < 1e-10:
|
130 |
+
values[j] = np.nan
|
131 |
+
else:
|
132 |
+
values[j] = numerator/denominator
|
133 |
+
|
134 |
+
valid_indices = ~np.isnan(values)
|
135 |
+
if np.any(valid_indices):
|
136 |
+
max_vals[i] = np.max(values[valid_indices])
|
137 |
+
else:
|
138 |
+
max_vals[i] = np.nan
|
139 |
+
|
140 |
+
return max_vals
|
141 |
+
|
142 |
+
@st.cache_data
|
143 |
+
def compute_min_t_expression(betas, z_a, y, t_samples=1000):
|
144 |
+
"""
|
145 |
+
Compute min_{t ∈ (-1/a, 0)} (y*beta*(a-1)*t + (a*t+1)*((y-1)*t-1)) / ((a*t+1)*(t^2+t))
|
146 |
+
"""
|
147 |
+
a = z_a
|
148 |
+
if a <= 0:
|
149 |
+
return np.full_like(betas, np.nan)
|
150 |
+
|
151 |
+
lower_bound = -1/a + 1e-10 # Avoid division by zero
|
152 |
+
t_values = np.linspace(lower_bound, -1e-10, t_samples)
|
153 |
+
|
154 |
+
min_vals = np.zeros_like(betas)
|
155 |
+
for i, beta in enumerate(betas):
|
156 |
+
values = np.zeros_like(t_values)
|
157 |
+
for j, t in enumerate(t_values):
|
158 |
+
numerator = y*beta*(a-1)*t + (a*t+1)*((y-1)*t-1)
|
159 |
+
denominator = (a*t+1)*(t**2+t)
|
160 |
+
if abs(denominator) < 1e-10:
|
161 |
+
values[j] = np.nan
|
162 |
+
else:
|
163 |
+
values[j] = numerator/denominator
|
164 |
+
|
165 |
+
valid_indices = ~np.isnan(values)
|
166 |
+
if np.any(valid_indices):
|
167 |
+
min_vals[i] = np.min(values[valid_indices])
|
168 |
+
else:
|
169 |
+
min_vals[i] = np.nan
|
170 |
+
|
171 |
+
return min_vals
|
172 |
+
|
173 |
@st.cache_data
|
174 |
def compute_derivatives(curve, betas):
|
175 |
"""Compute first and second derivatives of a curve"""
|
|
|
259 |
high_y_curve = compute_high_y_curve(betas, z_a, y)
|
260 |
alt_low_expr = compute_alternate_low_expr(betas, z_a, y)
|
261 |
|
262 |
+
# Compute the max/min expressions
|
263 |
+
max_k_curve = compute_max_k_expression(betas, z_a, y)
|
264 |
+
min_t_curve = compute_min_t_expression(betas, z_a, y)
|
265 |
+
|
266 |
# Compute both custom curves
|
267 |
custom_curve1 = None
|
268 |
custom_curve2 = None
|
|
|
275 |
if show_derivatives:
|
276 |
derivatives = compute_all_derivatives(betas, z_mins, z_maxs, None, high_y_curve,
|
277 |
alt_low_expr, custom_curve1, custom_curve2)
|
278 |
+
# Calculate derivatives for max_k and min_t curves
|
279 |
+
max_k_derivatives = compute_derivatives(max_k_curve, betas)
|
280 |
+
min_t_derivatives = compute_derivatives(min_t_curve, betas)
|
281 |
|
282 |
fig = go.Figure()
|
283 |
|
|
|
292 |
fig.add_trace(go.Scatter(x=betas, y=alt_low_expr, mode="markers+lines",
|
293 |
name="Low Expression", line=dict(color='green')))
|
294 |
|
295 |
+
# Add the new max/min curves
|
296 |
+
fig.add_trace(go.Scatter(x=betas, y=max_k_curve, mode="lines",
|
297 |
+
name="Max k Expression", line=dict(color='red', width=2)))
|
298 |
+
fig.add_trace(go.Scatter(x=betas, y=min_t_curve, mode="lines",
|
299 |
+
name="Min t Expression", line=dict(color='red', width=2)))
|
300 |
+
|
301 |
if custom_curve1 is not None:
|
302 |
fig.add_trace(go.Scatter(x=betas, y=custom_curve1, mode="markers+lines",
|
303 |
name="Custom 1 (s-based)", line=dict(color='purple')))
|
|
|
325 |
name=f"{name} d/dβ", line=dict(color=color, dash='dash')))
|
326 |
fig.add_trace(go.Scatter(x=betas, y=derivatives[key][1], mode="lines",
|
327 |
name=f"{name} d²/dβ²", line=dict(color=color, dash='dot')))
|
328 |
+
|
329 |
+
# Add derivatives for max_k and min_t curves
|
330 |
+
fig.add_trace(go.Scatter(x=betas, y=max_k_derivatives[0], mode="lines",
|
331 |
+
name="Max k d/dβ", line=dict(color='red', dash='dash')))
|
332 |
+
fig.add_trace(go.Scatter(x=betas, y=max_k_derivatives[1], mode="lines",
|
333 |
+
name="Max k d²/dβ²", line=dict(color='red', dash='dot')))
|
334 |
+
fig.add_trace(go.Scatter(x=betas, y=min_t_derivatives[0], mode="lines",
|
335 |
+
name="Min t d/dβ", line=dict(color='orange', dash='dash')))
|
336 |
+
fig.add_trace(go.Scatter(x=betas, y=min_t_derivatives[1], mode="lines",
|
337 |
+
name="Min t d²/dβ²", line=dict(color='orange', dash='dot')))
|
338 |
|
339 |
fig.update_layout(
|
340 |
title="Curves vs β: z*(β) Boundaries and Asymptotic Expressions",
|
|
|
508 |
- **Upper z*(β)** (Blue): Maximum z value where discriminant is zero
|
509 |
- **Lower z*(β)** (Light Blue): Minimum z value where discriminant is zero
|
510 |
- **High y Expression** (Green): Asymptotic approximation for high y values
|
511 |
+
- **Low Expression** (Green): Alternative asymptotic expression
|
512 |
+
- **Max k Expression** (Red): $\\max_{k \\in (0,\\infty)} \\frac{y\\beta (a-1)k + \\bigl(ak+1\\bigr)\\bigl((y-1)k-1\\bigr)}{(ak+1)(k^2+k)}$
|
513 |
+
- **Min t Expression** (Red): $\\min_{t \\in \\left(-\\frac{1}{a},\\, 0\\right)} \\frac{y\\beta (a-1)t + \\bigl(at+1\\bigr)\\bigl((y-1)t-1\\bigr)}{(at+1)(t^2+t)}$
|
514 |
- **Custom Expression 1** (Purple): Result from user-defined s substituted into the main formula
|
515 |
- **Custom Expression 2** (Magenta): Direct z(β) expression
|
516 |
""")
|