Lennard Schober commited on
Commit
d2bb714
·
1 Parent(s): 16a2246

Some changes

Browse files
Files changed (1) hide show
  1. app.py +70 -61
app.py CHANGED
@@ -38,29 +38,33 @@ def complex_heat_eq_solution(x, t, k, a, b, c):
38
  )
39
 
40
 
41
- def plot_heat_equation(m, approx_type):
42
  global glob_k, glob_a, glob_b, glob_c, n_x, n_t
43
 
 
 
 
 
44
  try:
45
- loaded_values = np.load(f"{approx_type}_m{m}.npz")
46
  except:
47
  raise gr.Error(f"First train the coefficients for {approx_type} and m = {m}")
48
  alpha = loaded_values["alpha"]
49
  Phi = loaded_values["Phi"]
50
 
51
  # Create grids for x and t
52
- x = np.linspace(0, 1, n_x) # Spatial grid
53
- t = np.linspace(0, 5, n_t) # Temporal grid
54
  X, T = np.meshgrid(x, t)
55
 
56
  # Compute the real solution over the grid
57
  U_real = complex_heat_eq_solution(X, T, glob_k, glob_a, glob_b, glob_c)
58
 
59
  # Compute the selected approximation
60
- U_approx = np.zeros_like(U_real)
61
- for i, t_val in enumerate(t):
62
- Phi_gff_at_t = Phi[i * n_x : (i + 1) * n_x]
63
- U_approx[i, :] = np.dot(Phi_gff_at_t, alpha)
64
 
65
  # Create the 3D plot with Plotly
66
  traces = []
@@ -133,11 +137,11 @@ def plot_heat_equation(m, approx_type):
133
  return fig
134
 
135
 
136
- def plot_errors(m, approx_type):
137
  global n_x, n_t
138
 
139
  try:
140
- loaded_values = np.load(f"{approx_type}_m{m}.npz")
141
  except:
142
  raise gr.Error(f"First train the coefficients for {approx_type} and m = {m}")
143
  alpha = loaded_values["alpha"]
@@ -154,8 +158,8 @@ def plot_errors(m, approx_type):
154
  # Compute the selected approximation
155
  U_approx = np.zeros_like(U_real)
156
  for i, t_val in enumerate(t):
157
- Phi_gff_at_t = Phi[i * n_x : (i + 1) * n_x]
158
- U_approx[i, :] = np.dot(Phi_gff_at_t, alpha)
159
 
160
  U_err = abs(U_approx - U_real)
161
 
@@ -229,19 +233,19 @@ def generate_data():
229
  return a_train, u_train, x, t
230
 
231
 
232
- def random_features(a, theta_j, kernel="SINE", k=0.5, t=1.0):
233
  """Compute random features with adjustable kernel width."""
234
  if kernel == "SINE":
235
- return np.sin(t * np.linalg.norm(a - theta_j, axis=-1))
236
  elif kernel == "GFF":
237
- return np.log(np.linalg.norm(a - theta_j, axis=-1)) / (2 * np.pi)
238
  else:
239
  raise ValueError("Unsupported kernel type!")
240
 
241
 
242
  def design_matrix(a, theta, kernel):
243
  """Construct design matrix."""
244
- return np.array([random_features(a, theta_j, kernel=kernel) for theta_j in theta]).T
245
 
246
 
247
  def learn_coefficients(Phi, u):
@@ -255,29 +259,7 @@ def approximate_solution(a, alpha, theta, kernel):
255
  return Phi @ alpha
256
 
257
 
258
- def polyfit2d(x, y, z, kx=3, ky=3, order=None):
259
- # grid coords
260
- x, y = np.meshgrid(x, y)
261
- # coefficient array, up to x^kx, y^ky
262
- coeffs = np.ones((kx + 1, ky + 1))
263
-
264
- # solve array
265
- a = np.zeros((coeffs.size, x.size))
266
-
267
- # for each coefficient produce array x^i, y^j
268
- for index, (j, i) in enumerate(np.ndindex(coeffs.shape)):
269
- # do not include powers greater than order
270
- if order is not None and i + j > order:
271
- arr = np.zeros_like(x)
272
- else:
273
- arr = coeffs[i, j] * x**i * y**j
274
- a[index] = arr.ravel()
275
-
276
- # do leastsq fitting and return leastsq result
277
- return np.linalg.lstsq(a.T, np.ravel(z), rcond=None)
278
-
279
-
280
- def train_coefficients(m, kernel):
281
  global glob_k, glob_a, glob_b, glob_c, n_x, n_t
282
  # Start time for training
283
  start_time = time.time()
@@ -286,36 +268,57 @@ def train_coefficients(m, kernel):
286
  a_train, u_train, x, t = generate_data()
287
 
288
  # Define random features
289
- theta = np.column_stack(
290
- (
291
- np.random.uniform(-1, 1, size=m), # First dimension: [-1, 1]
292
- np.random.uniform(-5, 5, size=m), # Second dimension: [-5, 5]
 
 
 
 
 
 
 
 
 
293
  )
294
- )
295
 
296
  # Construct design matrix and learn coefficients
297
  Phi = design_matrix(a_train, theta, kernel)
298
  alpha = learn_coefficients(Phi, u_train)
299
- # Validate and animate results
300
- u_real = np.array(
301
- [complex_heat_eq_solution(x, t_i, glob_k, glob_a, glob_b, glob_c) for t_i in t]
302
- )
303
- a_test = np.c_[np.meshgrid(x, t)[0].ravel(), np.meshgrid(x, t)[1].ravel()]
304
- u_approx = approximate_solution(a_test, alpha, theta, kernel).reshape(n_t, n_x)
305
 
306
  # Save values to the npz folder
307
  np.savez(
308
- f"{kernel}_m{m}.npz",
309
  alpha=alpha,
310
  kernel=kernel,
311
  Phi=Phi,
312
  theta=theta,
313
  )
314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  # Compute average error
316
- avg_err = np.mean(np.abs(u_real - u_approx))
317
 
318
- return f"Training completed in {time.time() - start_time:.2f} seconds. The average error is {avg_err}."
 
 
319
 
320
 
321
  def plot_function(k, a, b, c):
@@ -381,12 +384,14 @@ def plot_function(k, a, b, c):
381
  return fig
382
 
383
 
384
- def plot_all(m, kernel):
385
  # Generate the plot content (replace this with your actual plot logic)
386
  approx_fig = plot_heat_equation(
387
- m, kernel
388
  ) # Replace with your function for approx_plot
389
- error_fig = plot_errors(m, kernel) # Replace with your function for error_plot
 
 
390
 
391
  # Return the figures and make the plots visible
392
  return (
@@ -431,7 +436,6 @@ def create_gradio_ui():
431
  # Function parameter inputs
432
  gr.Markdown(markdown_content)
433
 
434
-
435
  with gr.Row():
436
  with gr.Column(min_width=500):
437
  k_slider = gr.Slider(
@@ -487,8 +491,13 @@ def create_gradio_ui():
487
  choices=[50, 250, 1000, 5000, 10000, 25000],
488
  value=1000,
489
  )
490
- # Output to show status
491
- output = gr.Textbox(label="Status", interactive=False)
 
 
 
 
 
492
 
493
  with gr.Column():
494
  # Button to train coefficients
@@ -496,7 +505,7 @@ def create_gradio_ui():
496
  # Function to trigger training and update dropdown
497
  train_button.click(
498
  fn=train_coefficients,
499
- inputs=[m_slider, kernel_dropdown],
500
  outputs=output,
501
  )
502
  approx_button = gr.Button("Plot Approximation")
@@ -509,7 +518,7 @@ def create_gradio_ui():
509
 
510
  approx_button.click(
511
  fn=plot_all,
512
- inputs=[m_slider, kernel_dropdown],
513
  outputs=[approx_plot, error_plot],
514
  )
515
 
 
38
  )
39
 
40
 
41
+ def plot_heat_equation(m, approx_type, quality, rand_or_det):
42
  global glob_k, glob_a, glob_b, glob_c, n_x, n_t
43
 
44
+ # Plot with more points than it was calculated
45
+ new_nx = 1 * n_x
46
+ new_nt = 1 * n_t
47
+
48
  try:
49
+ loaded_values = np.load(f"{approx_type}_m{m}_{str.lower(quality)}_{str.lower(rand_or_det)}.npz")
50
  except:
51
  raise gr.Error(f"First train the coefficients for {approx_type} and m = {m}")
52
  alpha = loaded_values["alpha"]
53
  Phi = loaded_values["Phi"]
54
 
55
  # Create grids for x and t
56
+ x = np.linspace(0, 1, new_nx) # Spatial grid
57
+ t = np.linspace(0, 5, new_nt) # Temporal grid
58
  X, T = np.meshgrid(x, t)
59
 
60
  # Compute the real solution over the grid
61
  U_real = complex_heat_eq_solution(X, T, glob_k, glob_a, glob_b, glob_c)
62
 
63
  # Compute the selected approximation
64
+ # Compute the approximations as a single matrix multiplication
65
+ Phi_reshaped = Phi.reshape(n_t, n_x, -1)
66
+ # The result will be of shape (n_t, n_x), as U_approx should match U_real's shape
67
+ U_approx = np.einsum("ijk,k->ij", Phi_reshaped, alpha)
68
 
69
  # Create the 3D plot with Plotly
70
  traces = []
 
137
  return fig
138
 
139
 
140
+ def plot_errors(m, approx_type, quality, rand_or_det):
141
  global n_x, n_t
142
 
143
  try:
144
+ loaded_values = np.load(f"{approx_type}_m{m}_{str.lower(quality)}_{str.lower(rand_or_det)}.npz")
145
  except:
146
  raise gr.Error(f"First train the coefficients for {approx_type} and m = {m}")
147
  alpha = loaded_values["alpha"]
 
158
  # Compute the selected approximation
159
  U_approx = np.zeros_like(U_real)
160
  for i, t_val in enumerate(t):
161
+ Phi_at_t = Phi[i * n_x : (i + 1) * n_x]
162
+ U_approx[i, :] = np.dot(Phi_at_t, alpha)
163
 
164
  U_err = abs(U_approx - U_real)
165
 
 
233
  return a_train, u_train, x, t
234
 
235
 
236
+ def features(a, theta_j, kernel="SINE", k=1, eps=1e-8):
237
  """Compute random features with adjustable kernel width."""
238
  if kernel == "SINE":
239
+ return np.sin(k * np.linalg.norm(a - theta_j, axis=-1) + eps)
240
  elif kernel == "GFF":
241
+ return np.log(np.linalg.norm(a - theta_j, axis=-1) + eps) / (2 * np.pi)
242
  else:
243
  raise ValueError("Unsupported kernel type!")
244
 
245
 
246
  def design_matrix(a, theta, kernel):
247
  """Construct design matrix."""
248
+ return np.array([features(a, theta_j, kernel=kernel) for theta_j in theta]).T
249
 
250
 
251
  def learn_coefficients(Phi, u):
 
259
  return Phi @ alpha
260
 
261
 
262
+ def train_coefficients(m, kernel, quality, rand_or_det):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  global glob_k, glob_a, glob_b, glob_c, n_x, n_t
264
  # Start time for training
265
  start_time = time.time()
 
268
  a_train, u_train, x, t = generate_data()
269
 
270
  # Define random features
271
+ if rand_or_det == "Random":
272
+ theta = np.column_stack(
273
+ (
274
+ np.random.uniform(-1, 1, size=m), # First dimension: [-1, 1]
275
+ np.random.uniform(-5, 5, size=m), # Second dimension: [-5, 5]
276
+ )
277
+ )
278
+ else:
279
+ theta = np.column_stack(
280
+ (
281
+ np.linspace(-1, 1, m), # First dimension: [-1, 1]
282
+ np.linspace(-5, 5, m), # Second dimension: [-5, 5]
283
+ )
284
  )
 
285
 
286
  # Construct design matrix and learn coefficients
287
  Phi = design_matrix(a_train, theta, kernel)
288
  alpha = learn_coefficients(Phi, u_train)
289
+
290
+ end_time = f"{time.time() - start_time:.2f}"
 
 
 
 
291
 
292
  # Save values to the npz folder
293
  np.savez(
294
+ f"{kernel}_m{m}_{str.lower(quality)}_{str.lower(rand_or_det)}.npz",
295
  alpha=alpha,
296
  kernel=kernel,
297
  Phi=Phi,
298
  theta=theta,
299
  )
300
 
301
+ # Create grids for x and t
302
+ # x_random = np.random.uniform(0, 1, 10 * n_x) # Spatial grid
303
+ # t_random = np.random.uniform(0, 5, 10 * n_t) # Temporal grid
304
+ # X, T = np.meshgrid(x_random, t_random) # Create the mesh grid
305
+ # Compute the real solution over the grid
306
+ # U_real = complex_heat_eq_solution(X, T, glob_k, glob_a, glob_b, glob_c)
307
+ # print(U_real.shape)
308
+ # print(U_real)
309
+ # Compute the selected approximation
310
+ # U_approx = np.zeros_like(U_real)
311
+ # for i, xpos in enumerate(x_random):
312
+ # for j, tpos in enumerate(t_random):
313
+ # Phi_at_x_t = test_approx([xpos, tpos], theta, kernel)
314
+ # U_approx[j, i] = np.dot(Phi_at_x_t, alpha)
315
+
316
  # Compute average error
317
+ # avg_err = np.mean(np.abs(U_real - U_approx))
318
 
319
+ return (
320
+ f"Training completed in {end_time} seconds." # The average error is {avg_err}."
321
+ )
322
 
323
 
324
  def plot_function(k, a, b, c):
 
384
  return fig
385
 
386
 
387
+ def plot_all(m, kernel, quality, rand_or_det):
388
  # Generate the plot content (replace this with your actual plot logic)
389
  approx_fig = plot_heat_equation(
390
+ m, kernel, quality, rand_or_det
391
  ) # Replace with your function for approx_plot
392
+ error_fig = plot_errors(
393
+ m, kernel, quality, rand_or_det
394
+ ) # Replace with your function for error_plot
395
 
396
  # Return the figures and make the plots visible
397
  return (
 
436
  # Function parameter inputs
437
  gr.Markdown(markdown_content)
438
 
 
439
  with gr.Row():
440
  with gr.Column(min_width=500):
441
  k_slider = gr.Slider(
 
491
  choices=[50, 250, 1000, 5000, 10000, 25000],
492
  value=1000,
493
  )
494
+ rand_det_dropdown = gr.Dropdown(
495
+ label="Choose Random / Deterministic",
496
+ choices=["Deterministic", "Random"],
497
+ value="Deterministic",
498
+ )
499
+ # Output to show status
500
+ output = gr.Textbox(label="Status", interactive=False)
501
 
502
  with gr.Column():
503
  # Button to train coefficients
 
505
  # Function to trigger training and update dropdown
506
  train_button.click(
507
  fn=train_coefficients,
508
+ inputs=[m_slider, kernel_dropdown, quality_dropdown, rand_det_dropdown],
509
  outputs=output,
510
  )
511
  approx_button = gr.Button("Plot Approximation")
 
518
 
519
  approx_button.click(
520
  fn=plot_all,
521
+ inputs=[m_slider, kernel_dropdown, quality_dropdown, rand_det_dropdown],
522
  outputs=[approx_plot, error_plot],
523
  )
524