euler314 commited on
Commit
3940b3d
·
verified ·
1 Parent(s): 13b3948

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -93
app.py CHANGED
@@ -1,11 +1,12 @@
1
  import streamlit as st
2
  import subprocess
3
  import os
 
 
 
4
  from PIL import Image
5
  import time
6
  import io
7
- import numpy as np
8
- import tempfile
9
 
10
  # Set page config
11
  st.set_page_config(
@@ -36,42 +37,31 @@ if not os.path.exists(cpp_file):
36
  st.error(f"C++ source file not found at: {cpp_file}")
37
  st.stop()
38
 
39
- # Compile the C++ code (we now have the required packages from packages.txt)
40
  try:
41
- compile_cmd = f"g++ -o {executable} {cpp_file} `pkg-config --cflags --libs opencv4` -std=c++11"
42
- compile_result = subprocess.run(
43
- compile_cmd,
44
- shell=True,
45
- capture_output=True,
46
- text=True
47
- )
48
 
49
- if compile_result.returncode != 0:
50
- st.error(f"Failed to compile C++ code: {compile_result.stderr}")
51
- # Try alternate compiler flag
52
- st.info("Attempting alternate compilation command...")
53
-
54
- compile_cmd = f"g++ -o {executable} {cpp_file} `pkg-config --cflags --libs opencv` -std=c++11"
55
  compile_result = subprocess.run(
56
- compile_cmd,
57
  shell=True,
58
  capture_output=True,
59
  text=True
60
  )
61
 
62
- if compile_result.returncode != 0:
63
- # Try with direct linking
64
- compile_cmd = f"g++ -o {executable} {cpp_file} -I/usr/include/opencv4 -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -std=c++11"
65
- compile_result = subprocess.run(
66
- compile_cmd,
67
- shell=True,
68
- capture_output=True,
69
- text=True
70
- )
71
-
72
- if compile_result.returncode != 0:
73
- st.error(f"All compilation attempts failed. Last error: {compile_result.stderr}")
74
- st.stop()
75
 
76
  # Make sure the executable is executable
77
  os.chmod(executable, 0o755)
@@ -85,86 +75,177 @@ except Exception as e:
85
  st.sidebar.header("Parameters")
86
 
87
  # Parameter inputs with defaults and validation
88
- col1, col2 = st.sidebar.columns(2)
89
- with col1:
90
- n = st.number_input("Sample size (n)", min_value=5, max_value=1000, value=100, step=5, help="Number of samples")
91
- a = st.number_input("Value for a", min_value=1.1, max_value=10.0, value=2.0, step=0.1, help="Parameter a > 1")
92
 
93
- with col2:
94
- p = st.number_input("Dimension (p)", min_value=5, max_value=1000, value=50, step=5, help="Dimensionality")
95
- y = st.number_input("Value for y", min_value=0.1, max_value=10.0, value=1.0, step=0.1, help="Parameter y > 0")
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Generate button
98
  if st.sidebar.button("Generate Plot", type="primary"):
99
  # Show progress
100
- with st.spinner("Generating eigenvalue analysis plot... This may take a few moments."):
101
- # Run the C++ executable with the parameters
102
- output_file = os.path.join(output_dir, "eigenvalue_analysis.png")
 
 
 
103
 
104
  # Delete previous output if exists
105
- if os.path.exists(output_file):
106
- os.remove(output_file)
107
 
108
  # Execute the C++ program
109
- try:
110
- cmd = [executable, str(n), str(p), str(a), str(y), output_file]
111
-
112
- process = subprocess.Popen(
113
- cmd,
114
- stdout=subprocess.PIPE,
115
- stderr=subprocess.PIPE,
116
- text=True
117
- )
118
-
119
- # Show output in a status area
120
- status_area = st.empty()
121
-
122
- while True:
123
- output = process.stdout.readline()
124
- if output == '' and process.poll() is not None:
125
- break
126
- if output:
127
- status_area.info(output.strip())
128
-
129
- return_code = process.poll()
130
-
131
- if return_code != 0:
132
- error = process.stderr.read()
133
- st.error(f"Error executing the analysis: {error}")
134
- else:
135
- status_area.success("Analysis completed successfully!")
136
-
137
- # Wait a moment to ensure the file is written
138
- time.sleep(1)
139
-
140
- # Display the image if it exists
141
- if os.path.exists(output_file):
142
- img = Image.open(output_file)
143
- st.image(img, use_column_width=True)
144
-
145
- # Provide download button
146
- with open(output_file, "rb") as file:
147
- btn = st.download_button(
148
- label="Download Plot",
149
- data=file,
150
- file_name=f"eigenvalue_analysis_n{n}_p{p}_a{a}_y{y}.png",
151
- mime="image/png"
152
- )
153
  else:
154
- st.error("Plot generation failed. Output file not found.")
 
155
 
156
- except Exception as e:
157
- st.error(f"An error occurred: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
  # Show example plot on startup or previous results
160
  example_file = os.path.join(output_dir, "eigenvalue_analysis.png")
161
- if not os.path.exists(example_file):
162
- st.info("👈 Set parameters and click 'Generate Plot' to create a visualization.")
163
- else:
164
  # Show the most recent plot by default
165
  st.subheader("Current Plot")
166
  img = Image.open(example_file)
167
  st.image(img, use_column_width=True)
 
 
168
 
169
  # Add information about the analysis
170
  with st.expander("About Eigenvalue Analysis"):
@@ -183,7 +264,8 @@ with st.expander("About Eigenvalue Analysis"):
183
  - **n**: Sample size
184
  - **p**: Dimension
185
  - **a**: Value > 1 that affects the distribution of eigenvalues
186
- - **y**: Value that affects scaling
 
187
 
188
  ### Mathematical Formulas
189
 
 
1
  import streamlit as st
2
  import subprocess
3
  import os
4
+ import json
5
+ import numpy as np
6
+ import matplotlib.pyplot as plt
7
  from PIL import Image
8
  import time
9
  import io
 
 
10
 
11
  # Set page config
12
  st.set_page_config(
 
37
  st.error(f"C++ source file not found at: {cpp_file}")
38
  st.stop()
39
 
40
+ # Compile the C++ code with the right OpenCV libraries
41
  try:
42
+ st.info("Compiling C++ code...")
43
+ compile_commands = [
44
+ f"g++ -o {executable} {cpp_file} `pkg-config --cflags --libs opencv4` -std=c++11",
45
+ f"g++ -o {executable} {cpp_file} `pkg-config --cflags --libs opencv` -std=c++11",
46
+ f"g++ -o {executable} {cpp_file} -I/usr/include/opencv4 -lopencv_core -lopencv_imgproc -std=c++11"
47
+ ]
 
48
 
49
+ compiled = False
50
+ for cmd in compile_commands:
 
 
 
 
51
  compile_result = subprocess.run(
52
+ cmd,
53
  shell=True,
54
  capture_output=True,
55
  text=True
56
  )
57
 
58
+ if compile_result.returncode == 0:
59
+ compiled = True
60
+ break
61
+
62
+ if not compiled:
63
+ st.error("All compilation attempts failed. Please check the system requirements.")
64
+ st.stop()
 
 
 
 
 
 
65
 
66
  # Make sure the executable is executable
67
  os.chmod(executable, 0o755)
 
75
  st.sidebar.header("Parameters")
76
 
77
  # Parameter inputs with defaults and validation
78
+ n = st.sidebar.number_input("Sample size (n)", min_value=5, max_value=1000, value=100, step=5, help="Number of samples")
79
+ p = st.sidebar.number_input("Dimension (p)", min_value=5, max_value=1000, value=50, step=5, help="Dimensionality")
80
+ a = st.sidebar.number_input("Value for a", min_value=1.1, max_value=10.0, value=2.0, step=0.1, help="Parameter a > 1")
 
81
 
82
+ # Automatically calculate y = p/n (as requested)
83
+ y = p/n
84
+ st.sidebar.text(f"Value for y = p/n: {y:.4f}")
85
+
86
+ # Add fineness control
87
+ fineness = st.sidebar.slider(
88
+ "Calculation fineness",
89
+ min_value=20,
90
+ max_value=500,
91
+ value=100,
92
+ step=10,
93
+ help="Higher values give smoother curves but take longer to calculate"
94
+ )
95
 
96
  # Generate button
97
  if st.sidebar.button("Generate Plot", type="primary"):
98
  # Show progress
99
+ progress_bar = st.progress(0)
100
+ status_text = st.empty()
101
+
102
+ try:
103
+ # Run the C++ executable with the parameters in JSON output mode
104
+ data_file = os.path.join(output_dir, "eigenvalue_data.json")
105
 
106
  # Delete previous output if exists
107
+ if os.path.exists(data_file):
108
+ os.remove(data_file)
109
 
110
  # Execute the C++ program
111
+ cmd = [executable, str(n), str(p), str(a), str(y), str(fineness), data_file]
112
+
113
+ process = subprocess.Popen(
114
+ cmd,
115
+ stdout=subprocess.PIPE,
116
+ stderr=subprocess.PIPE,
117
+ text=True
118
+ )
119
+
120
+ # Show output in a status area
121
+ status_text.text("Starting calculations...")
122
+
123
+ last_progress = 0
124
+ while process.poll() is None:
125
+ output = process.stdout.readline()
126
+ if output:
127
+ if output.startswith("PROGRESS:"):
128
+ try:
129
+ # Update progress bar
130
+ progress_value = float(output.split(":")[1].strip())
131
+ progress_bar.progress(progress_value)
132
+ last_progress = progress_value
133
+ status_text.text(f"Calculating... {int(progress_value * 100)}% complete")
134
+ except:
135
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  else:
137
+ status_text.text(output.strip())
138
+ time.sleep(0.1)
139
 
140
+ return_code = process.poll()
141
+
142
+ if return_code != 0:
143
+ error = process.stderr.read()
144
+ st.error(f"Error executing the analysis: {error}")
145
+ else:
146
+ progress_bar.progress(1.0)
147
+ status_text.text("Calculations complete! Generating plot...")
148
+
149
+ # Load the results from the JSON file
150
+ with open(data_file, 'r') as f:
151
+ data = json.load(f)
152
+
153
+ # Create a better plot with matplotlib
154
+ beta_values = np.array(data['beta_values'])
155
+ max_eigenvalues = np.array(data['max_eigenvalues'])
156
+ min_eigenvalues = np.array(data['min_eigenvalues'])
157
+ theoretical_max = np.array(data['theoretical_max'])
158
+ theoretical_min = np.array(data['theoretical_min'])
159
+
160
+ # Create the plot
161
+ fig, ax = plt.subplots(figsize=(12, 9), dpi=100)
162
+
163
+ # Set the background color
164
+ fig.patch.set_facecolor('#f5f5f5')
165
+ ax.set_facecolor('#f0f0f0')
166
+
167
+ # Plot the data
168
+ ax.plot(beta_values, max_eigenvalues, 'r-', linewidth=2,
169
+ label='Empirical Max Eigenvalue', marker='o', markevery=len(beta_values)//20)
170
+ ax.plot(beta_values, min_eigenvalues, 'b-', linewidth=2,
171
+ label='Empirical Min Eigenvalue', marker='o', markevery=len(beta_values)//20)
172
+ ax.plot(beta_values, theoretical_max, 'g-', linewidth=2,
173
+ label='Theoretical Max Function', marker='D', markevery=len(beta_values)//20)
174
+ ax.plot(beta_values, theoretical_min, 'm-', linewidth=2,
175
+ label='Theoretical Min Function', marker='D', markevery=len(beta_values)//20)
176
+
177
+ # Add grid
178
+ ax.grid(True, linestyle='--', alpha=0.7)
179
+
180
+ # Set labels and title
181
+ ax.set_xlabel('β', fontsize=14)
182
+ ax.set_ylabel('Eigenvalues', fontsize=14)
183
+ ax.set_title(f'Eigenvalue Analysis: n={n}, p={p}, a={a}, y={y:.4f}', fontsize=16)
184
+
185
+ # Add legend
186
+ ax.legend(loc='best', fontsize=12, framealpha=0.9)
187
+
188
+ # Add formulas as text
189
+ formula_text1 = r"Max Function: $\max_{k \in (0,\infty)} \frac{y\beta(a-1)k + (ak+1)((y-1)k-1)}{(ak+1)(k^2+k)y}$"
190
+ formula_text2 = r"Min Function: $\min_{t \in (-1/a,0)} \frac{y\beta(a-1)t + (at+1)((y-1)t-1)}{(at+1)(t^2+t)y}$"
191
+
192
+ plt.figtext(0.02, 0.02, formula_text1, fontsize=10, color='green')
193
+ plt.figtext(0.55, 0.02, formula_text2, fontsize=10, color='purple')
194
+
195
+ # Adjust layout
196
+ plt.tight_layout(rect=[0, 0.05, 1, 0.95])
197
+
198
+ # Save the plot to a buffer
199
+ buf = io.BytesIO()
200
+ plt.savefig(buf, format='png', dpi=100)
201
+ buf.seek(0)
202
+
203
+ # Save to file
204
+ output_file = os.path.join(output_dir, "eigenvalue_analysis.png")
205
+ plt.savefig(output_file, format='png', dpi=100)
206
+ plt.close()
207
+
208
+ # Display the image in Streamlit
209
+ status_text.success("Analysis completed successfully!")
210
+ st.image(buf, use_column_width=True)
211
+
212
+ # Provide download button
213
+ with open(output_file, "rb") as file:
214
+ btn = st.download_button(
215
+ label="Download Plot",
216
+ data=file,
217
+ file_name=f"eigenvalue_analysis_n{n}_p{p}_a{a}_y{y:.4f}.png",
218
+ mime="image/png"
219
+ )
220
+
221
+ # Add some statistics
222
+ st.subheader("Statistical Summary")
223
+ col1, col2 = st.columns(2)
224
+
225
+ with col1:
226
+ st.write("### Maximum Eigenvalues")
227
+ st.write(f"Empirical Max: {max(max_eigenvalues):.6f}")
228
+ st.write(f"Theoretical Max: {max(theoretical_max):.6f}")
229
+ st.write(f"Difference: {abs(max(max_eigenvalues) - max(theoretical_max)):.6f}")
230
+
231
+ with col2:
232
+ st.write("### Minimum Eigenvalues")
233
+ st.write(f"Empirical Min: {min(min_eigenvalues):.6f}")
234
+ st.write(f"Theoretical Min: {min(theoretical_min):.6f}")
235
+ st.write(f"Difference: {abs(min(min_eigenvalues) - min(theoretical_min)):.6f}")
236
+
237
+ except Exception as e:
238
+ st.error(f"An error occurred: {str(e)}")
239
 
240
  # Show example plot on startup or previous results
241
  example_file = os.path.join(output_dir, "eigenvalue_analysis.png")
242
+ if os.path.exists(example_file):
 
 
243
  # Show the most recent plot by default
244
  st.subheader("Current Plot")
245
  img = Image.open(example_file)
246
  st.image(img, use_column_width=True)
247
+ else:
248
+ st.info("👈 Set parameters and click 'Generate Plot' to create a visualization.")
249
 
250
  # Add information about the analysis
251
  with st.expander("About Eigenvalue Analysis"):
 
264
  - **n**: Sample size
265
  - **p**: Dimension
266
  - **a**: Value > 1 that affects the distribution of eigenvalues
267
+ - **y**: Value calculated as p/n that affects scaling
268
+ - **Fineness**: Controls the number of points calculated along the β range (0 to 1)
269
 
270
  ### Mathematical Formulas
271