euler314 commited on
Commit
319d05d
·
verified ·
1 Parent(s): 7a1ddff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -48
app.py CHANGED
@@ -3,6 +3,7 @@ import sympy as sp
3
  import numpy as np
4
  import plotly.graph_objects as go
5
  from scipy.optimize import fsolve
 
6
 
7
  # Configure Streamlit for Hugging Face Spaces
8
  st.set_page_config(
@@ -336,62 +337,70 @@ def generate_root_plots(beta, y, z_a, z_min, z_max, n_points):
336
  xaxis_title="z", yaxis_title="Re{s}", hovermode="x unified")
337
  return fig_im, fig_re
338
 
339
- # New function for the eigenvalue distribution
340
  @st.cache_data
341
- def compute_eigenvalue_distribution(z_a, y, beta, x_min, x_max, num_points, epsilon=1e-6):
342
  """
343
- Compute the eigenvalue distribution (ESD) of B_n as n ∞.
344
 
345
- B_n = (1/n)XX*
346
- X is a p×n matrix with p/n y as n → ∞
347
- All elements of X are i.i.d. with distribution β·δ_a + (1-β)·δ_1
348
- """
349
- x_values = np.linspace(x_min, x_max, num_points)
350
- density_values = np.zeros(num_points)
351
 
352
- second_moment = beta * (z_a**2) + (1-beta) * 1
 
 
 
 
353
 
354
- for i, x in enumerate(x_values):
355
- z = complex(x, epsilon)
356
-
357
- # Define the fixed-point equation for the Stieltjes transform
358
- def fixed_point_equation(m_real_imag):
359
- m_real, m_imag = m_real_imag
360
- m = complex(m_real, m_imag)
361
-
362
- term1 = beta / (z_a - z - y * m * second_moment)
363
- term2 = (1-beta) / (1 - z - y * m * second_moment)
364
-
365
- result = term1 + term2 - m
366
-
367
- return [result.real, result.imag]
368
 
369
- # Solve the fixed-point equation
370
- initial_guess = [-0.1, -0.1] # Initial guess for the Stieltjes transform
371
- m_solution = fsolve(fixed_point_equation, initial_guess)
372
- m = complex(m_solution[0], m_solution[1])
373
 
374
- # Compute the density using the Stieltjes inversion formula
375
- density_values[i] = -1/np.pi * m.imag
 
376
 
377
- # Ensure density is non-negative
378
- density_values = np.maximum(density_values, 0)
379
-
380
- return x_values, density_values
381
 
382
- def generate_esd_plot(z_a, y, beta, x_min, x_max, num_points=1000):
383
  """
384
- Generate a plot of the eigenvalue distribution.
385
  """
386
- x_values, density_values = compute_eigenvalue_distribution(z_a, y, beta, x_min, x_max, num_points)
 
 
 
 
 
 
 
 
 
 
387
 
 
388
  fig = go.Figure()
389
  fig.add_trace(go.Scatter(x=x_values, y=density_values, mode="lines",
390
  name="Eigenvalue Density", line=dict(color='blue', width=2)))
391
 
 
 
 
 
 
392
  fig.update_layout(
393
- title=f"Eigenvalue Distribution (β={beta:.3f}, y={y:.3f}, z_a={z_a:.3f})",
394
- xaxis_title="x",
395
  yaxis_title="Density",
396
  hovermode="x unified"
397
  )
@@ -470,9 +479,9 @@ with tab2:
470
 
471
  # Add new settings for eigenvalue distribution
472
  st.subheader("Eigenvalue Distribution Settings")
473
- x_min = st.number_input("x_min", value=0.0, key="x_min_esd")
474
- x_max = st.number_input("x_max", value=5.0, key="x_max_esd")
475
- num_points = st.slider("Number of points", min_value=100, max_value=2000, value=1000, step=100, key="num_points_esd")
476
 
477
  if st.button("Compute", key="tab2_button"):
478
  with col2:
@@ -481,18 +490,24 @@ with tab2:
481
  st.plotly_chart(fig_im, use_container_width=True)
482
  st.plotly_chart(fig_re, use_container_width=True)
483
 
484
- # Add eigenvalue distribution plot
485
- fig_esd = generate_esd_plot(z_a_2, y_2, beta, x_min, x_max, num_points)
486
- st.plotly_chart(fig_esd, use_container_width=True)
 
487
 
488
  st.markdown("""
489
  ### Eigenvalue Distribution Explanation
490
- This plot shows the limiting eigenvalue distribution of B_n = (1/n)XX* as n → ∞, where:
491
- - X is a p×n matrix with p/n y
492
  - Elements of X are i.i.d. following distribution β·δ_a + (1-β)·δ_1
493
  - a = z_a, y = y, β = β
494
 
495
- The distribution is calculated using the Stieltjes transform approach.
 
 
 
 
 
496
  """)
497
 
498
  # ----- Tab 3: Differential Analysis -----
 
3
  import numpy as np
4
  import plotly.graph_objects as go
5
  from scipy.optimize import fsolve
6
+ from scipy.stats import gaussian_kde
7
 
8
  # Configure Streamlit for Hugging Face Spaces
9
  st.set_page_config(
 
337
  xaxis_title="z", yaxis_title="Re{s}", hovermode="x unified")
338
  return fig_im, fig_re
339
 
340
+ # New function for computing eigenvalue distribution directly
341
  @st.cache_data
342
+ def compute_eigenvalue_distribution_direct(z_a, y, beta, n, num_samples=10):
343
  """
344
+ Compute the eigenvalue distribution by directly generating random matrices and computing eigenvalues.
345
 
346
+ Parameters:
347
+ - z_a: The value 'a' in the distribution β·δ_a + (1-β)·δ_1
348
+ - y: The asymptotic ratio p/n
349
+ - beta: The mixing coefficient in the distribution
350
+ - n: Size of the matrix dimension n
351
+ - num_samples: Number of random matrices to generate for averaging
352
 
353
+ Returns:
354
+ - all_eigenvalues: Array of all eigenvalues from all samples
355
+ """
356
+ p = int(y * n) # Calculate p based on aspect ratio y
357
+ all_eigenvalues = []
358
 
359
+ for _ in range(num_samples):
360
+ # Generate random matrix X with elements following β·δ_a + (1-β)·δ_1
361
+ # This means each element is 'a' with probability β, and 1 with probability (1-β)
362
+ random_values = np.random.choice([z_a, 1.0], size=(p, n), p=[beta, 1-beta])
 
 
 
 
 
 
 
 
 
 
363
 
364
+ # Compute B_n = (1/n)XX*
365
+ X = random_values
366
+ XX_star = X @ X.T
367
+ B_n = XX_star / n
368
 
369
+ # Compute eigenvalues
370
+ eigenvalues = np.linalg.eigvalsh(B_n)
371
+ all_eigenvalues.extend(eigenvalues)
372
 
373
+ return np.array(all_eigenvalues)
 
 
 
374
 
375
+ def generate_esd_plot_direct(z_a, y, beta, n, num_samples=10, bandwidth=0.1):
376
  """
377
+ Generate a plot of the eigenvalue distribution using KDE.
378
  """
379
+ # Compute eigenvalues
380
+ eigenvalues = compute_eigenvalue_distribution_direct(z_a, y, beta, n, num_samples)
381
+
382
+ # Use KDE to estimate the density
383
+ kde = gaussian_kde(eigenvalues, bw_method=bandwidth)
384
+
385
+ # Generate points for plotting
386
+ x_min = max(0, np.min(eigenvalues) - 0.5)
387
+ x_max = np.max(eigenvalues) + 0.5
388
+ x_values = np.linspace(x_min, x_max, 1000)
389
+ density_values = kde(x_values)
390
 
391
+ # Create the plot
392
  fig = go.Figure()
393
  fig.add_trace(go.Scatter(x=x_values, y=density_values, mode="lines",
394
  name="Eigenvalue Density", line=dict(color='blue', width=2)))
395
 
396
+ # Add individual eigenvalue points as a rug plot
397
+ fig.add_trace(go.Scatter(x=eigenvalues, y=np.zeros_like(eigenvalues),
398
+ mode="markers", name="Eigenvalues",
399
+ marker=dict(color='red', size=3, opacity=0.5)))
400
+
401
  fig.update_layout(
402
+ title=f"Eigenvalue Distribution (β={beta:.3f}, y={y:.3f}, z_a={z_a:.3f}, n={n})",
403
+ xaxis_title="Eigenvalue",
404
  yaxis_title="Density",
405
  hovermode="x unified"
406
  )
 
479
 
480
  # Add new settings for eigenvalue distribution
481
  st.subheader("Eigenvalue Distribution Settings")
482
+ matrix_size = st.slider("Matrix size (n)", min_value=50, max_value=1000, value=200, step=50, key="matrix_size")
483
+ num_samples = st.slider("Number of matrix samples", min_value=1, max_value=50, value=10, step=1, key="num_samples")
484
+ bandwidth = st.slider("KDE bandwidth", min_value=0.01, max_value=0.5, value=0.1, step=0.01, key="kde_bandwidth")
485
 
486
  if st.button("Compute", key="tab2_button"):
487
  with col2:
 
490
  st.plotly_chart(fig_im, use_container_width=True)
491
  st.plotly_chart(fig_re, use_container_width=True)
492
 
493
+ # Add eigenvalue distribution plot with direct computation and KDE
494
+ with st.spinner("Computing eigenvalue distribution..."):
495
+ fig_esd = generate_esd_plot_direct(z_a_2, y_2, beta, matrix_size, num_samples, bandwidth)
496
+ st.plotly_chart(fig_esd, use_container_width=True)
497
 
498
  st.markdown("""
499
  ### Eigenvalue Distribution Explanation
500
+ This plot shows the eigenvalue distribution of B_n = (1/n)XX* where:
501
+ - X is a p×n matrix with p/n = y
502
  - Elements of X are i.i.d. following distribution β·δ_a + (1-β)·δ_1
503
  - a = z_a, y = y, β = β
504
 
505
+ The distribution is computed by:
506
+ 1. Directly generating random matrices with the specified distribution
507
+ 2. Computing the eigenvalues of B_n
508
+ 3. Using Kernel Density Estimation (KDE) to visualize the distribution
509
+
510
+ Red markers at the bottom indicate individual eigenvalues.
511
  """)
512
 
513
  # ----- Tab 3: Differential Analysis -----