joel-woodfield commited on
Commit
888bb2a
·
1 Parent(s): 9292daf

Add current point info monitoring

Browse files
backend/src/__pycache__/optimization_logic.cpython-314.pyc ADDED
Binary file (27.9 kB). View file
 
backend/src/optimization_logic.py CHANGED
@@ -2,8 +2,19 @@ import numpy as np
2
  from sympy import lambdify, Expr
3
 
4
 
 
 
 
 
 
 
 
 
 
 
 
5
  def gd_univariate(
6
- function: Expr,
7
  x0: float,
8
  learning_rate: float,
9
  momentum: float,
@@ -16,9 +27,12 @@ def gd_univariate(
16
  """
17
  f = lambdify('x', function, modules=['numpy'])
18
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
19
 
20
  x_values = [x0]
21
  y_values = [f(x0)]
 
 
22
 
23
  x = x0
24
  for i in range(steps - 1):
@@ -26,14 +40,18 @@ def gd_univariate(
26
  m = 0
27
  else:
28
  m = momentum * (x_values[-1] - x_values[-2])
29
-
30
  x = x - learning_rate * f_prime(x) + m
31
  x_values.append(x)
32
  y_values.append(f(x))
 
 
33
 
34
  return {
35
  "x": x_values,
36
  "y": y_values,
 
 
37
  }
38
 
39
 
@@ -48,31 +66,40 @@ def gd_bivariate(
48
  f = lambdify(('x', 'y'), function, modules=['numpy'])
49
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
50
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
51
 
52
  x_values = [x0]
53
  y_values = [y0]
54
  z_values = [f(x0, y0)]
 
 
55
 
56
  x = x0
57
  y = y0
58
- for i in range(steps -1):
59
  if i == 0:
60
  mx = 0
61
  my = 0
62
  else:
63
  mx = momentum * (x_values[-1] - x_values[-2])
64
  my = momentum * (y_values[-1] - y_values[-2])
65
-
66
  x = x - learning_rate * fx(x, y) + mx
67
  y = y - learning_rate * fy(x, y) + my
68
  x_values.append(x)
69
  y_values.append(y)
70
  z_values.append(f(x, y))
 
 
71
 
72
  return {
73
  "x": x_values,
74
  "y": y_values,
75
  "z": z_values,
 
 
76
  }
77
 
78
 
@@ -85,9 +112,12 @@ def nesterov_univariate(
85
  ) -> dict:
86
  f = lambdify('x', function, modules=['numpy'])
87
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
88
 
89
  x_values = [x0]
90
  y_values = [f(x0)]
 
 
91
 
92
  x = x0
93
  for i in range(steps - 1):
@@ -95,16 +125,20 @@ def nesterov_univariate(
95
  m = 0
96
  else:
97
  m = momentum * (x_values[-1] - x_values[-2])
98
-
99
  x_lookahead = x - m
100
  x = x_lookahead - learning_rate * f_prime(x_lookahead)
101
 
102
  x_values.append(x)
103
  y_values.append(f(x))
 
 
104
 
105
  return {
106
  "x": x_values,
107
  "y": y_values,
 
 
108
  }
109
 
110
 
@@ -119,10 +153,15 @@ def nesterov_bivariate(
119
  f = lambdify(('x', 'y'), function, modules=['numpy'])
120
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
121
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
122
 
123
  x_values = [x0]
124
  y_values = [y0]
125
  z_values = [f(x0, y0)]
 
 
126
 
127
  x = x0
128
  y = y0
@@ -133,7 +172,7 @@ def nesterov_bivariate(
133
  else:
134
  mx = momentum * (x_values[-1] - x_values[-2])
135
  my = momentum * (y_values[-1] - y_values[-2])
136
-
137
  x_lookahead = x - mx
138
  y_lookahead = y - my
139
 
@@ -143,11 +182,15 @@ def nesterov_bivariate(
143
  x_values.append(x)
144
  y_values.append(y)
145
  z_values.append(f(x, y))
 
 
146
 
147
  return {
148
  "x": x_values,
149
  "y": y_values,
150
  "z": z_values,
 
 
151
  }
152
 
153
 
@@ -162,16 +205,22 @@ def newton_univariate(
162
 
163
  x_values = [x0]
164
  y_values = [f(x0)]
 
 
165
 
166
  x = x0
167
  for i in range(steps - 1):
168
  x = x - f_prime(x) / f_prime_prime(x)
169
  x_values.append(x)
170
  y_values.append(f(x))
 
 
171
 
172
  return {
173
  "x": x_values,
174
  "y": y_values,
 
 
175
  }
176
 
177
 
@@ -191,6 +240,8 @@ def newton_bivariate(
191
  x_values = [x0]
192
  y_values = [y0]
193
  z_values = [f(x0, y0)]
 
 
194
 
195
  x = x0
196
  y = y0
@@ -216,11 +267,15 @@ def newton_bivariate(
216
  x_values.append(x)
217
  y_values.append(y)
218
  z_values.append(f(x, y))
 
 
219
 
220
  return {
221
  "x": x_values,
222
  "y": y_values,
223
  "z": z_values,
 
 
224
  }
225
 
226
 
@@ -233,9 +288,12 @@ def adagrad_univariate(
233
  ) -> dict:
234
  f = lambdify('x', function, modules=['numpy'])
235
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
236
 
237
  x_values = [x0]
238
  y_values = [f(x0)]
 
 
239
 
240
  x = x0
241
  v = 0 # accumulated squared gradients
@@ -246,10 +304,14 @@ def adagrad_univariate(
246
 
247
  x_values.append(x)
248
  y_values.append(f(x))
 
 
249
 
250
  return {
251
  "x": x_values,
252
  "y": y_values,
 
 
253
  }
254
 
255
 
@@ -264,10 +326,15 @@ def adagrad_bivariate(
264
  f = lambdify(('x', 'y'), function, modules=['numpy'])
265
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
266
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
267
 
268
  x_values = [x0]
269
  y_values = [y0]
270
  z_values = [f(x0, y0)]
 
 
271
 
272
  x = x0
273
  y = y0
@@ -286,11 +353,15 @@ def adagrad_bivariate(
286
  x_values.append(x)
287
  y_values.append(y)
288
  z_values.append(f(x, y))
 
 
289
 
290
  return {
291
  "x": x_values,
292
  "y": y_values,
293
  "z": z_values,
 
 
294
  }
295
 
296
 
@@ -304,9 +375,12 @@ def rmsprop_univariate(
304
  ) -> dict:
305
  f = lambdify('x', function, modules=['numpy'])
306
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
307
 
308
  x_values = [x0]
309
  y_values = [f(x0)]
 
 
310
 
311
  x = x0
312
  v = 0 # exponentially weighted average of squared gradients
@@ -317,12 +391,16 @@ def rmsprop_univariate(
317
 
318
  x_values.append(x)
319
  y_values.append(f(x))
 
 
320
 
321
  return {
322
  "x": x_values,
323
  "y": y_values,
 
 
324
  }
325
-
326
 
327
  def rmsprop_bivariate(
328
  function: Expr,
@@ -336,10 +414,15 @@ def rmsprop_bivariate(
336
  f = lambdify(('x', 'y'), function, modules=['numpy'])
337
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
338
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
339
 
340
  x_values = [x0]
341
  y_values = [y0]
342
  z_values = [f(x0, y0)]
 
 
343
 
344
  x = x0
345
  y = y0
@@ -358,11 +441,15 @@ def rmsprop_bivariate(
358
  x_values.append(x)
359
  y_values.append(y)
360
  z_values.append(f(x, y))
 
 
361
 
362
  return {
363
  "x": x_values,
364
  "y": y_values,
365
  "z": z_values,
 
 
366
  }
367
 
368
 
@@ -376,9 +463,12 @@ def adadelta_univariate(
376
  ) -> dict:
377
  f = lambdify('x', function, modules=['numpy'])
378
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
379
 
380
  x_values = [x0]
381
  y_values = [f(x0)]
 
 
382
 
383
  x = x0
384
  v = 0 # exponentially weighted average of squared gradients
@@ -393,10 +483,14 @@ def adadelta_univariate(
393
 
394
  x_values.append(x)
395
  y_values.append(f(x))
 
 
396
 
397
  return {
398
  "x": x_values,
399
  "y": y_values,
 
 
400
  }
401
 
402
 
@@ -412,10 +506,15 @@ def adadelta_bivariate(
412
  f = lambdify(('x', 'y'), function, modules=['numpy'])
413
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
414
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
415
 
416
  x_values = [x0]
417
  y_values = [y0]
418
  z_values = [f(x0, y0)]
 
 
419
 
420
  x = x0
421
  y = y0
@@ -443,11 +542,15 @@ def adadelta_bivariate(
443
  x_values.append(x)
444
  y_values.append(y)
445
  z_values.append(f(x, y))
 
 
446
 
447
  return {
448
  "x": x_values,
449
  "y": y_values,
450
  "z": z_values,
 
 
451
  }
452
 
453
 
@@ -462,9 +565,12 @@ def adam_univariate(
462
  ) -> dict:
463
  f = lambdify('x', function, modules=['numpy'])
464
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
465
 
466
  x_values = [x0]
467
  y_values = [f(x0)]
 
 
468
 
469
  x = x0
470
  m = 0 # first moment
@@ -481,10 +587,14 @@ def adam_univariate(
481
 
482
  x_values.append(x)
483
  y_values.append(f(x))
 
 
484
 
485
  return {
486
  "x": x_values,
487
  "y": y_values,
 
 
488
  }
489
 
490
 
@@ -501,10 +611,15 @@ def adam_bivariate(
501
  f = lambdify(('x', 'y'), function, modules=['numpy'])
502
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
503
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
504
 
505
  x_values = [x0]
506
  y_values = [y0]
507
  z_values = [f(x0, y0)]
 
 
508
 
509
  x = x0
510
  y = y0
@@ -536,9 +651,13 @@ def adam_bivariate(
536
  x_values.append(x)
537
  y_values.append(y)
538
  z_values.append(f(x, y))
 
 
539
 
540
  return {
541
  "x": x_values,
542
  "y": y_values,
543
  "z": z_values,
544
- }
 
 
 
2
  from sympy import lambdify, Expr
3
 
4
 
5
+ def _gradient_values(fx, fy, x: float, y: float) -> list:
6
+ return [float(fx(x, y)), float(fy(x, y))]
7
+
8
+
9
+ def _hessian_values(fxx, fxy, fyy, x: float, y: float) -> list:
10
+ return [
11
+ [float(fxx(x, y)), float(fxy(x, y))],
12
+ [float(fxy(x, y)), float(fyy(x, y))],
13
+ ]
14
+
15
+
16
  def gd_univariate(
17
+ function: Expr,
18
  x0: float,
19
  learning_rate: float,
20
  momentum: float,
 
27
  """
28
  f = lambdify('x', function, modules=['numpy'])
29
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
30
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
31
 
32
  x_values = [x0]
33
  y_values = [f(x0)]
34
+ derivative_values = [f_prime(x0)]
35
+ second_derivative_values = [f_prime_prime(x0)]
36
 
37
  x = x0
38
  for i in range(steps - 1):
 
40
  m = 0
41
  else:
42
  m = momentum * (x_values[-1] - x_values[-2])
43
+
44
  x = x - learning_rate * f_prime(x) + m
45
  x_values.append(x)
46
  y_values.append(f(x))
47
+ derivative_values.append(f_prime(x))
48
+ second_derivative_values.append(f_prime_prime(x))
49
 
50
  return {
51
  "x": x_values,
52
  "y": y_values,
53
+ "derivative": derivative_values,
54
+ "secondDerivative": second_derivative_values,
55
  }
56
 
57
 
 
66
  f = lambdify(('x', 'y'), function, modules=['numpy'])
67
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
68
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
69
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
70
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
71
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
72
 
73
  x_values = [x0]
74
  y_values = [y0]
75
  z_values = [f(x0, y0)]
76
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
77
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
78
 
79
  x = x0
80
  y = y0
81
+ for i in range(steps - 1):
82
  if i == 0:
83
  mx = 0
84
  my = 0
85
  else:
86
  mx = momentum * (x_values[-1] - x_values[-2])
87
  my = momentum * (y_values[-1] - y_values[-2])
88
+
89
  x = x - learning_rate * fx(x, y) + mx
90
  y = y - learning_rate * fy(x, y) + my
91
  x_values.append(x)
92
  y_values.append(y)
93
  z_values.append(f(x, y))
94
+ gradient_values.append(_gradient_values(fx, fy, x, y))
95
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
96
 
97
  return {
98
  "x": x_values,
99
  "y": y_values,
100
  "z": z_values,
101
+ "gradient": gradient_values,
102
+ "hessian": hessian_values,
103
  }
104
 
105
 
 
112
  ) -> dict:
113
  f = lambdify('x', function, modules=['numpy'])
114
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
115
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
116
 
117
  x_values = [x0]
118
  y_values = [f(x0)]
119
+ derivative_values = [f_prime(x0)]
120
+ second_derivative_values = [f_prime_prime(x0)]
121
 
122
  x = x0
123
  for i in range(steps - 1):
 
125
  m = 0
126
  else:
127
  m = momentum * (x_values[-1] - x_values[-2])
128
+
129
  x_lookahead = x - m
130
  x = x_lookahead - learning_rate * f_prime(x_lookahead)
131
 
132
  x_values.append(x)
133
  y_values.append(f(x))
134
+ derivative_values.append(f_prime(x))
135
+ second_derivative_values.append(f_prime_prime(x))
136
 
137
  return {
138
  "x": x_values,
139
  "y": y_values,
140
+ "derivative": derivative_values,
141
+ "secondDerivative": second_derivative_values,
142
  }
143
 
144
 
 
153
  f = lambdify(('x', 'y'), function, modules=['numpy'])
154
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
155
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
156
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
157
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
158
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
159
 
160
  x_values = [x0]
161
  y_values = [y0]
162
  z_values = [f(x0, y0)]
163
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
164
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
165
 
166
  x = x0
167
  y = y0
 
172
  else:
173
  mx = momentum * (x_values[-1] - x_values[-2])
174
  my = momentum * (y_values[-1] - y_values[-2])
175
+
176
  x_lookahead = x - mx
177
  y_lookahead = y - my
178
 
 
182
  x_values.append(x)
183
  y_values.append(y)
184
  z_values.append(f(x, y))
185
+ gradient_values.append(_gradient_values(fx, fy, x, y))
186
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
187
 
188
  return {
189
  "x": x_values,
190
  "y": y_values,
191
  "z": z_values,
192
+ "gradient": gradient_values,
193
+ "hessian": hessian_values,
194
  }
195
 
196
 
 
205
 
206
  x_values = [x0]
207
  y_values = [f(x0)]
208
+ derivative_values = [f_prime(x0)]
209
+ second_derivative_values = [f_prime_prime(x0)]
210
 
211
  x = x0
212
  for i in range(steps - 1):
213
  x = x - f_prime(x) / f_prime_prime(x)
214
  x_values.append(x)
215
  y_values.append(f(x))
216
+ derivative_values.append(f_prime(x))
217
+ second_derivative_values.append(f_prime_prime(x))
218
 
219
  return {
220
  "x": x_values,
221
  "y": y_values,
222
+ "derivative": derivative_values,
223
+ "secondDerivative": second_derivative_values,
224
  }
225
 
226
 
 
240
  x_values = [x0]
241
  y_values = [y0]
242
  z_values = [f(x0, y0)]
243
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
244
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
245
 
246
  x = x0
247
  y = y0
 
267
  x_values.append(x)
268
  y_values.append(y)
269
  z_values.append(f(x, y))
270
+ gradient_values.append(_gradient_values(fx, fy, x, y))
271
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
272
 
273
  return {
274
  "x": x_values,
275
  "y": y_values,
276
  "z": z_values,
277
+ "gradient": gradient_values,
278
+ "hessian": hessian_values,
279
  }
280
 
281
 
 
288
  ) -> dict:
289
  f = lambdify('x', function, modules=['numpy'])
290
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
291
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
292
 
293
  x_values = [x0]
294
  y_values = [f(x0)]
295
+ derivative_values = [f_prime(x0)]
296
+ second_derivative_values = [f_prime_prime(x0)]
297
 
298
  x = x0
299
  v = 0 # accumulated squared gradients
 
304
 
305
  x_values.append(x)
306
  y_values.append(f(x))
307
+ derivative_values.append(f_prime(x))
308
+ second_derivative_values.append(f_prime_prime(x))
309
 
310
  return {
311
  "x": x_values,
312
  "y": y_values,
313
+ "derivative": derivative_values,
314
+ "secondDerivative": second_derivative_values,
315
  }
316
 
317
 
 
326
  f = lambdify(('x', 'y'), function, modules=['numpy'])
327
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
328
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
329
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
330
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
331
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
332
 
333
  x_values = [x0]
334
  y_values = [y0]
335
  z_values = [f(x0, y0)]
336
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
337
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
338
 
339
  x = x0
340
  y = y0
 
353
  x_values.append(x)
354
  y_values.append(y)
355
  z_values.append(f(x, y))
356
+ gradient_values.append(_gradient_values(fx, fy, x, y))
357
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
358
 
359
  return {
360
  "x": x_values,
361
  "y": y_values,
362
  "z": z_values,
363
+ "gradient": gradient_values,
364
+ "hessian": hessian_values,
365
  }
366
 
367
 
 
375
  ) -> dict:
376
  f = lambdify('x', function, modules=['numpy'])
377
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
378
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
379
 
380
  x_values = [x0]
381
  y_values = [f(x0)]
382
+ derivative_values = [f_prime(x0)]
383
+ second_derivative_values = [f_prime_prime(x0)]
384
 
385
  x = x0
386
  v = 0 # exponentially weighted average of squared gradients
 
391
 
392
  x_values.append(x)
393
  y_values.append(f(x))
394
+ derivative_values.append(f_prime(x))
395
+ second_derivative_values.append(f_prime_prime(x))
396
 
397
  return {
398
  "x": x_values,
399
  "y": y_values,
400
+ "derivative": derivative_values,
401
+ "secondDerivative": second_derivative_values,
402
  }
403
+
404
 
405
  def rmsprop_bivariate(
406
  function: Expr,
 
414
  f = lambdify(('x', 'y'), function, modules=['numpy'])
415
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
416
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
417
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
418
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
419
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
420
 
421
  x_values = [x0]
422
  y_values = [y0]
423
  z_values = [f(x0, y0)]
424
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
425
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
426
 
427
  x = x0
428
  y = y0
 
441
  x_values.append(x)
442
  y_values.append(y)
443
  z_values.append(f(x, y))
444
+ gradient_values.append(_gradient_values(fx, fy, x, y))
445
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
446
 
447
  return {
448
  "x": x_values,
449
  "y": y_values,
450
  "z": z_values,
451
+ "gradient": gradient_values,
452
+ "hessian": hessian_values,
453
  }
454
 
455
 
 
463
  ) -> dict:
464
  f = lambdify('x', function, modules=['numpy'])
465
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
466
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
467
 
468
  x_values = [x0]
469
  y_values = [f(x0)]
470
+ derivative_values = [f_prime(x0)]
471
+ second_derivative_values = [f_prime_prime(x0)]
472
 
473
  x = x0
474
  v = 0 # exponentially weighted average of squared gradients
 
483
 
484
  x_values.append(x)
485
  y_values.append(f(x))
486
+ derivative_values.append(f_prime(x))
487
+ second_derivative_values.append(f_prime_prime(x))
488
 
489
  return {
490
  "x": x_values,
491
  "y": y_values,
492
+ "derivative": derivative_values,
493
+ "secondDerivative": second_derivative_values,
494
  }
495
 
496
 
 
506
  f = lambdify(('x', 'y'), function, modules=['numpy'])
507
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
508
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
509
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
510
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
511
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
512
 
513
  x_values = [x0]
514
  y_values = [y0]
515
  z_values = [f(x0, y0)]
516
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
517
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
518
 
519
  x = x0
520
  y = y0
 
542
  x_values.append(x)
543
  y_values.append(y)
544
  z_values.append(f(x, y))
545
+ gradient_values.append(_gradient_values(fx, fy, x, y))
546
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
547
 
548
  return {
549
  "x": x_values,
550
  "y": y_values,
551
  "z": z_values,
552
+ "gradient": gradient_values,
553
+ "hessian": hessian_values,
554
  }
555
 
556
 
 
565
  ) -> dict:
566
  f = lambdify('x', function, modules=['numpy'])
567
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
568
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
569
 
570
  x_values = [x0]
571
  y_values = [f(x0)]
572
+ derivative_values = [f_prime(x0)]
573
+ second_derivative_values = [f_prime_prime(x0)]
574
 
575
  x = x0
576
  m = 0 # first moment
 
587
 
588
  x_values.append(x)
589
  y_values.append(f(x))
590
+ derivative_values.append(f_prime(x))
591
+ second_derivative_values.append(f_prime_prime(x))
592
 
593
  return {
594
  "x": x_values,
595
  "y": y_values,
596
+ "derivative": derivative_values,
597
+ "secondDerivative": second_derivative_values,
598
  }
599
 
600
 
 
611
  f = lambdify(('x', 'y'), function, modules=['numpy'])
612
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
613
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
614
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
615
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
616
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
617
 
618
  x_values = [x0]
619
  y_values = [y0]
620
  z_values = [f(x0, y0)]
621
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
622
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
623
 
624
  x = x0
625
  y = y0
 
651
  x_values.append(x)
652
  y_values.append(y)
653
  z_values.append(f(x, y))
654
+ gradient_values.append(_gradient_values(fx, fy, x, y))
655
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
656
 
657
  return {
658
  "x": x_values,
659
  "y": y_values,
660
  "z": z_values,
661
+ "gradient": gradient_values,
662
+ "hessian": hessian_values,
663
+ }
backend/src/optimization_manager.py CHANGED
@@ -337,4 +337,3 @@ class OptimizationManager:
337
  )
338
  else:
339
  raise ValueError("Unsupported algorithm for bivariate mode")
340
-
 
337
  )
338
  else:
339
  raise ValueError("Unsupported algorithm for bivariate mode")
 
dist/assets/{index-xwMlQNfu.js → index-DOAl0ZPy.js} RENAMED
The diff for this file is too large to render. See raw diff
 
dist/assets/{pyodide.worker-Dr32d4MW.js → pyodide.worker-CqQKSeoe.js} RENAMED
@@ -1,4 +1,4 @@
1
- (function(){"use strict";var i=`import numpy as np
2
  from sympy import (
3
  lambdify,
4
  symbols,
@@ -337,13 +337,23 @@ class OptimizationManager:
337
  )
338
  else:
339
  raise ValueError("Unsupported algorithm for bivariate mode")
340
-
341
  `,l=`import numpy as np
342
  from sympy import lambdify, Expr
343
 
344
 
 
 
 
 
 
 
 
 
 
 
 
345
  def gd_univariate(
346
- function: Expr,
347
  x0: float,
348
  learning_rate: float,
349
  momentum: float,
@@ -356,9 +366,12 @@ def gd_univariate(
356
  """
357
  f = lambdify('x', function, modules=['numpy'])
358
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
359
 
360
  x_values = [x0]
361
  y_values = [f(x0)]
 
 
362
 
363
  x = x0
364
  for i in range(steps - 1):
@@ -366,14 +379,18 @@ def gd_univariate(
366
  m = 0
367
  else:
368
  m = momentum * (x_values[-1] - x_values[-2])
369
-
370
  x = x - learning_rate * f_prime(x) + m
371
  x_values.append(x)
372
  y_values.append(f(x))
 
 
373
 
374
  return {
375
  "x": x_values,
376
  "y": y_values,
 
 
377
  }
378
 
379
 
@@ -388,31 +405,40 @@ def gd_bivariate(
388
  f = lambdify(('x', 'y'), function, modules=['numpy'])
389
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
390
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
391
 
392
  x_values = [x0]
393
  y_values = [y0]
394
  z_values = [f(x0, y0)]
 
 
395
 
396
  x = x0
397
  y = y0
398
- for i in range(steps -1):
399
  if i == 0:
400
  mx = 0
401
  my = 0
402
  else:
403
  mx = momentum * (x_values[-1] - x_values[-2])
404
  my = momentum * (y_values[-1] - y_values[-2])
405
-
406
  x = x - learning_rate * fx(x, y) + mx
407
  y = y - learning_rate * fy(x, y) + my
408
  x_values.append(x)
409
  y_values.append(y)
410
  z_values.append(f(x, y))
 
 
411
 
412
  return {
413
  "x": x_values,
414
  "y": y_values,
415
  "z": z_values,
 
 
416
  }
417
 
418
 
@@ -425,9 +451,12 @@ def nesterov_univariate(
425
  ) -> dict:
426
  f = lambdify('x', function, modules=['numpy'])
427
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
428
 
429
  x_values = [x0]
430
  y_values = [f(x0)]
 
 
431
 
432
  x = x0
433
  for i in range(steps - 1):
@@ -435,16 +464,20 @@ def nesterov_univariate(
435
  m = 0
436
  else:
437
  m = momentum * (x_values[-1] - x_values[-2])
438
-
439
  x_lookahead = x - m
440
  x = x_lookahead - learning_rate * f_prime(x_lookahead)
441
 
442
  x_values.append(x)
443
  y_values.append(f(x))
 
 
444
 
445
  return {
446
  "x": x_values,
447
  "y": y_values,
 
 
448
  }
449
 
450
 
@@ -459,10 +492,15 @@ def nesterov_bivariate(
459
  f = lambdify(('x', 'y'), function, modules=['numpy'])
460
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
461
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
462
 
463
  x_values = [x0]
464
  y_values = [y0]
465
  z_values = [f(x0, y0)]
 
 
466
 
467
  x = x0
468
  y = y0
@@ -473,7 +511,7 @@ def nesterov_bivariate(
473
  else:
474
  mx = momentum * (x_values[-1] - x_values[-2])
475
  my = momentum * (y_values[-1] - y_values[-2])
476
-
477
  x_lookahead = x - mx
478
  y_lookahead = y - my
479
 
@@ -483,11 +521,15 @@ def nesterov_bivariate(
483
  x_values.append(x)
484
  y_values.append(y)
485
  z_values.append(f(x, y))
 
 
486
 
487
  return {
488
  "x": x_values,
489
  "y": y_values,
490
  "z": z_values,
 
 
491
  }
492
 
493
 
@@ -502,16 +544,22 @@ def newton_univariate(
502
 
503
  x_values = [x0]
504
  y_values = [f(x0)]
 
 
505
 
506
  x = x0
507
  for i in range(steps - 1):
508
  x = x - f_prime(x) / f_prime_prime(x)
509
  x_values.append(x)
510
  y_values.append(f(x))
 
 
511
 
512
  return {
513
  "x": x_values,
514
  "y": y_values,
 
 
515
  }
516
 
517
 
@@ -531,6 +579,8 @@ def newton_bivariate(
531
  x_values = [x0]
532
  y_values = [y0]
533
  z_values = [f(x0, y0)]
 
 
534
 
535
  x = x0
536
  y = y0
@@ -556,11 +606,15 @@ def newton_bivariate(
556
  x_values.append(x)
557
  y_values.append(y)
558
  z_values.append(f(x, y))
 
 
559
 
560
  return {
561
  "x": x_values,
562
  "y": y_values,
563
  "z": z_values,
 
 
564
  }
565
 
566
 
@@ -573,9 +627,12 @@ def adagrad_univariate(
573
  ) -> dict:
574
  f = lambdify('x', function, modules=['numpy'])
575
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
576
 
577
  x_values = [x0]
578
  y_values = [f(x0)]
 
 
579
 
580
  x = x0
581
  v = 0 # accumulated squared gradients
@@ -586,10 +643,14 @@ def adagrad_univariate(
586
 
587
  x_values.append(x)
588
  y_values.append(f(x))
 
 
589
 
590
  return {
591
  "x": x_values,
592
  "y": y_values,
 
 
593
  }
594
 
595
 
@@ -604,10 +665,15 @@ def adagrad_bivariate(
604
  f = lambdify(('x', 'y'), function, modules=['numpy'])
605
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
606
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
607
 
608
  x_values = [x0]
609
  y_values = [y0]
610
  z_values = [f(x0, y0)]
 
 
611
 
612
  x = x0
613
  y = y0
@@ -626,11 +692,15 @@ def adagrad_bivariate(
626
  x_values.append(x)
627
  y_values.append(y)
628
  z_values.append(f(x, y))
 
 
629
 
630
  return {
631
  "x": x_values,
632
  "y": y_values,
633
  "z": z_values,
 
 
634
  }
635
 
636
 
@@ -644,9 +714,12 @@ def rmsprop_univariate(
644
  ) -> dict:
645
  f = lambdify('x', function, modules=['numpy'])
646
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
647
 
648
  x_values = [x0]
649
  y_values = [f(x0)]
 
 
650
 
651
  x = x0
652
  v = 0 # exponentially weighted average of squared gradients
@@ -657,12 +730,16 @@ def rmsprop_univariate(
657
 
658
  x_values.append(x)
659
  y_values.append(f(x))
 
 
660
 
661
  return {
662
  "x": x_values,
663
  "y": y_values,
 
 
664
  }
665
-
666
 
667
  def rmsprop_bivariate(
668
  function: Expr,
@@ -676,10 +753,15 @@ def rmsprop_bivariate(
676
  f = lambdify(('x', 'y'), function, modules=['numpy'])
677
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
678
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
679
 
680
  x_values = [x0]
681
  y_values = [y0]
682
  z_values = [f(x0, y0)]
 
 
683
 
684
  x = x0
685
  y = y0
@@ -698,11 +780,15 @@ def rmsprop_bivariate(
698
  x_values.append(x)
699
  y_values.append(y)
700
  z_values.append(f(x, y))
 
 
701
 
702
  return {
703
  "x": x_values,
704
  "y": y_values,
705
  "z": z_values,
 
 
706
  }
707
 
708
 
@@ -716,9 +802,12 @@ def adadelta_univariate(
716
  ) -> dict:
717
  f = lambdify('x', function, modules=['numpy'])
718
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
719
 
720
  x_values = [x0]
721
  y_values = [f(x0)]
 
 
722
 
723
  x = x0
724
  v = 0 # exponentially weighted average of squared gradients
@@ -733,10 +822,14 @@ def adadelta_univariate(
733
 
734
  x_values.append(x)
735
  y_values.append(f(x))
 
 
736
 
737
  return {
738
  "x": x_values,
739
  "y": y_values,
 
 
740
  }
741
 
742
 
@@ -752,10 +845,15 @@ def adadelta_bivariate(
752
  f = lambdify(('x', 'y'), function, modules=['numpy'])
753
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
754
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
755
 
756
  x_values = [x0]
757
  y_values = [y0]
758
  z_values = [f(x0, y0)]
 
 
759
 
760
  x = x0
761
  y = y0
@@ -783,11 +881,15 @@ def adadelta_bivariate(
783
  x_values.append(x)
784
  y_values.append(y)
785
  z_values.append(f(x, y))
 
 
786
 
787
  return {
788
  "x": x_values,
789
  "y": y_values,
790
  "z": z_values,
 
 
791
  }
792
 
793
 
@@ -802,9 +904,12 @@ def adam_univariate(
802
  ) -> dict:
803
  f = lambdify('x', function, modules=['numpy'])
804
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
 
805
 
806
  x_values = [x0]
807
  y_values = [f(x0)]
 
 
808
 
809
  x = x0
810
  m = 0 # first moment
@@ -821,10 +926,14 @@ def adam_univariate(
821
 
822
  x_values.append(x)
823
  y_values.append(f(x))
 
 
824
 
825
  return {
826
  "x": x_values,
827
  "y": y_values,
 
 
828
  }
829
 
830
 
@@ -841,10 +950,15 @@ def adam_bivariate(
841
  f = lambdify(('x', 'y'), function, modules=['numpy'])
842
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
843
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
 
 
 
844
 
845
  x_values = [x0]
846
  y_values = [y0]
847
  z_values = [f(x0, y0)]
 
 
848
 
849
  x = x0
850
  y = y0
@@ -876,9 +990,14 @@ def adam_bivariate(
876
  x_values.append(x)
877
  y_values.append(y)
878
  z_values.append(f(x, y))
 
 
879
 
880
  return {
881
  "x": x_values,
882
  "y": y_values,
883
  "z": z_values,
884
- }`;const o="https://cdn.jsdelivr.net/pyodide/v0.26.1/full/pyodide.mjs";let e=null,t=null;async function r(){const{loadPyodide:n}=await import(o);e=await n({indexURL:"https://cdn.jsdelivr.net/pyodide/v0.26.1/full/"}),await e.loadPackage(["numpy","sympy"]),e.FS.writeFile("optimization_logic.py",l),e.FS.writeFile("optimization_manager.py",i),e.runPython("from optimization_manager import OptimizationManager; manager = OptimizationManager();"),t=e.globals.get("manager"),t||console.error("Failed to initialize optimization manager"),self.postMessage({type:"READY"})}function s(n){if(!n)return null;try{const a=n.toJs({dict_converter:Object.fromEntries});n.destroy&&n.destroy(),self.postMessage({type:"RESULT",data:a})}catch(a){console.error("Error handling Python result:",a)}}self.onmessage=async n=>{const a=n.data;if(!t){console.warn("Pyodide is not ready yet");return}switch(a.type){case"INIT":const f=e.toPy(a.settings);s(t.handle_update_settings(f));break;case"NEXT_STEP":s(t.handle_next_step());break;case"PREV_STEP":s(t.handle_prev_step());break;case"RESET":s(t.handle_reset());break;default:console.error("Unknown message type:",a);break}},r()})();
 
 
 
 
1
+ (function(){"use strict";var s=`import numpy as np
2
  from sympy import (
3
  lambdify,
4
  symbols,
 
337
  )
338
  else:
339
  raise ValueError("Unsupported algorithm for bivariate mode")
 
340
  `,l=`import numpy as np
341
  from sympy import lambdify, Expr
342
 
343
 
344
+ def _gradient_values(fx, fy, x: float, y: float) -> list:
345
+ return [float(fx(x, y)), float(fy(x, y))]
346
+
347
+
348
+ def _hessian_values(fxx, fxy, fyy, x: float, y: float) -> list:
349
+ return [
350
+ [float(fxx(x, y)), float(fxy(x, y))],
351
+ [float(fxy(x, y)), float(fyy(x, y))],
352
+ ]
353
+
354
+
355
  def gd_univariate(
356
+ function: Expr,
357
  x0: float,
358
  learning_rate: float,
359
  momentum: float,
 
366
  """
367
  f = lambdify('x', function, modules=['numpy'])
368
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
369
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
370
 
371
  x_values = [x0]
372
  y_values = [f(x0)]
373
+ derivative_values = [f_prime(x0)]
374
+ second_derivative_values = [f_prime_prime(x0)]
375
 
376
  x = x0
377
  for i in range(steps - 1):
 
379
  m = 0
380
  else:
381
  m = momentum * (x_values[-1] - x_values[-2])
382
+
383
  x = x - learning_rate * f_prime(x) + m
384
  x_values.append(x)
385
  y_values.append(f(x))
386
+ derivative_values.append(f_prime(x))
387
+ second_derivative_values.append(f_prime_prime(x))
388
 
389
  return {
390
  "x": x_values,
391
  "y": y_values,
392
+ "derivative": derivative_values,
393
+ "secondDerivative": second_derivative_values,
394
  }
395
 
396
 
 
405
  f = lambdify(('x', 'y'), function, modules=['numpy'])
406
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
407
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
408
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
409
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
410
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
411
 
412
  x_values = [x0]
413
  y_values = [y0]
414
  z_values = [f(x0, y0)]
415
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
416
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
417
 
418
  x = x0
419
  y = y0
420
+ for i in range(steps - 1):
421
  if i == 0:
422
  mx = 0
423
  my = 0
424
  else:
425
  mx = momentum * (x_values[-1] - x_values[-2])
426
  my = momentum * (y_values[-1] - y_values[-2])
427
+
428
  x = x - learning_rate * fx(x, y) + mx
429
  y = y - learning_rate * fy(x, y) + my
430
  x_values.append(x)
431
  y_values.append(y)
432
  z_values.append(f(x, y))
433
+ gradient_values.append(_gradient_values(fx, fy, x, y))
434
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
435
 
436
  return {
437
  "x": x_values,
438
  "y": y_values,
439
  "z": z_values,
440
+ "gradient": gradient_values,
441
+ "hessian": hessian_values,
442
  }
443
 
444
 
 
451
  ) -> dict:
452
  f = lambdify('x', function, modules=['numpy'])
453
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
454
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
455
 
456
  x_values = [x0]
457
  y_values = [f(x0)]
458
+ derivative_values = [f_prime(x0)]
459
+ second_derivative_values = [f_prime_prime(x0)]
460
 
461
  x = x0
462
  for i in range(steps - 1):
 
464
  m = 0
465
  else:
466
  m = momentum * (x_values[-1] - x_values[-2])
467
+
468
  x_lookahead = x - m
469
  x = x_lookahead - learning_rate * f_prime(x_lookahead)
470
 
471
  x_values.append(x)
472
  y_values.append(f(x))
473
+ derivative_values.append(f_prime(x))
474
+ second_derivative_values.append(f_prime_prime(x))
475
 
476
  return {
477
  "x": x_values,
478
  "y": y_values,
479
+ "derivative": derivative_values,
480
+ "secondDerivative": second_derivative_values,
481
  }
482
 
483
 
 
492
  f = lambdify(('x', 'y'), function, modules=['numpy'])
493
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
494
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
495
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
496
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
497
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
498
 
499
  x_values = [x0]
500
  y_values = [y0]
501
  z_values = [f(x0, y0)]
502
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
503
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
504
 
505
  x = x0
506
  y = y0
 
511
  else:
512
  mx = momentum * (x_values[-1] - x_values[-2])
513
  my = momentum * (y_values[-1] - y_values[-2])
514
+
515
  x_lookahead = x - mx
516
  y_lookahead = y - my
517
 
 
521
  x_values.append(x)
522
  y_values.append(y)
523
  z_values.append(f(x, y))
524
+ gradient_values.append(_gradient_values(fx, fy, x, y))
525
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
526
 
527
  return {
528
  "x": x_values,
529
  "y": y_values,
530
  "z": z_values,
531
+ "gradient": gradient_values,
532
+ "hessian": hessian_values,
533
  }
534
 
535
 
 
544
 
545
  x_values = [x0]
546
  y_values = [f(x0)]
547
+ derivative_values = [f_prime(x0)]
548
+ second_derivative_values = [f_prime_prime(x0)]
549
 
550
  x = x0
551
  for i in range(steps - 1):
552
  x = x - f_prime(x) / f_prime_prime(x)
553
  x_values.append(x)
554
  y_values.append(f(x))
555
+ derivative_values.append(f_prime(x))
556
+ second_derivative_values.append(f_prime_prime(x))
557
 
558
  return {
559
  "x": x_values,
560
  "y": y_values,
561
+ "derivative": derivative_values,
562
+ "secondDerivative": second_derivative_values,
563
  }
564
 
565
 
 
579
  x_values = [x0]
580
  y_values = [y0]
581
  z_values = [f(x0, y0)]
582
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
583
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
584
 
585
  x = x0
586
  y = y0
 
606
  x_values.append(x)
607
  y_values.append(y)
608
  z_values.append(f(x, y))
609
+ gradient_values.append(_gradient_values(fx, fy, x, y))
610
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
611
 
612
  return {
613
  "x": x_values,
614
  "y": y_values,
615
  "z": z_values,
616
+ "gradient": gradient_values,
617
+ "hessian": hessian_values,
618
  }
619
 
620
 
 
627
  ) -> dict:
628
  f = lambdify('x', function, modules=['numpy'])
629
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
630
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
631
 
632
  x_values = [x0]
633
  y_values = [f(x0)]
634
+ derivative_values = [f_prime(x0)]
635
+ second_derivative_values = [f_prime_prime(x0)]
636
 
637
  x = x0
638
  v = 0 # accumulated squared gradients
 
643
 
644
  x_values.append(x)
645
  y_values.append(f(x))
646
+ derivative_values.append(f_prime(x))
647
+ second_derivative_values.append(f_prime_prime(x))
648
 
649
  return {
650
  "x": x_values,
651
  "y": y_values,
652
+ "derivative": derivative_values,
653
+ "secondDerivative": second_derivative_values,
654
  }
655
 
656
 
 
665
  f = lambdify(('x', 'y'), function, modules=['numpy'])
666
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
667
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
668
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
669
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
670
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
671
 
672
  x_values = [x0]
673
  y_values = [y0]
674
  z_values = [f(x0, y0)]
675
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
676
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
677
 
678
  x = x0
679
  y = y0
 
692
  x_values.append(x)
693
  y_values.append(y)
694
  z_values.append(f(x, y))
695
+ gradient_values.append(_gradient_values(fx, fy, x, y))
696
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
697
 
698
  return {
699
  "x": x_values,
700
  "y": y_values,
701
  "z": z_values,
702
+ "gradient": gradient_values,
703
+ "hessian": hessian_values,
704
  }
705
 
706
 
 
714
  ) -> dict:
715
  f = lambdify('x', function, modules=['numpy'])
716
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
717
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
718
 
719
  x_values = [x0]
720
  y_values = [f(x0)]
721
+ derivative_values = [f_prime(x0)]
722
+ second_derivative_values = [f_prime_prime(x0)]
723
 
724
  x = x0
725
  v = 0 # exponentially weighted average of squared gradients
 
730
 
731
  x_values.append(x)
732
  y_values.append(f(x))
733
+ derivative_values.append(f_prime(x))
734
+ second_derivative_values.append(f_prime_prime(x))
735
 
736
  return {
737
  "x": x_values,
738
  "y": y_values,
739
+ "derivative": derivative_values,
740
+ "secondDerivative": second_derivative_values,
741
  }
742
+
743
 
744
  def rmsprop_bivariate(
745
  function: Expr,
 
753
  f = lambdify(('x', 'y'), function, modules=['numpy'])
754
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
755
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
756
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
757
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
758
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
759
 
760
  x_values = [x0]
761
  y_values = [y0]
762
  z_values = [f(x0, y0)]
763
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
764
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
765
 
766
  x = x0
767
  y = y0
 
780
  x_values.append(x)
781
  y_values.append(y)
782
  z_values.append(f(x, y))
783
+ gradient_values.append(_gradient_values(fx, fy, x, y))
784
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
785
 
786
  return {
787
  "x": x_values,
788
  "y": y_values,
789
  "z": z_values,
790
+ "gradient": gradient_values,
791
+ "hessian": hessian_values,
792
  }
793
 
794
 
 
802
  ) -> dict:
803
  f = lambdify('x', function, modules=['numpy'])
804
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
805
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
806
 
807
  x_values = [x0]
808
  y_values = [f(x0)]
809
+ derivative_values = [f_prime(x0)]
810
+ second_derivative_values = [f_prime_prime(x0)]
811
 
812
  x = x0
813
  v = 0 # exponentially weighted average of squared gradients
 
822
 
823
  x_values.append(x)
824
  y_values.append(f(x))
825
+ derivative_values.append(f_prime(x))
826
+ second_derivative_values.append(f_prime_prime(x))
827
 
828
  return {
829
  "x": x_values,
830
  "y": y_values,
831
+ "derivative": derivative_values,
832
+ "secondDerivative": second_derivative_values,
833
  }
834
 
835
 
 
845
  f = lambdify(('x', 'y'), function, modules=['numpy'])
846
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
847
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
848
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
849
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
850
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
851
 
852
  x_values = [x0]
853
  y_values = [y0]
854
  z_values = [f(x0, y0)]
855
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
856
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
857
 
858
  x = x0
859
  y = y0
 
881
  x_values.append(x)
882
  y_values.append(y)
883
  z_values.append(f(x, y))
884
+ gradient_values.append(_gradient_values(fx, fy, x, y))
885
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
886
 
887
  return {
888
  "x": x_values,
889
  "y": y_values,
890
  "z": z_values,
891
+ "gradient": gradient_values,
892
+ "hessian": hessian_values,
893
  }
894
 
895
 
 
904
  ) -> dict:
905
  f = lambdify('x', function, modules=['numpy'])
906
  f_prime = lambdify('x', function.diff('x'), modules=['numpy'])
907
+ f_prime_prime = lambdify('x', function.diff('x', 2), modules=['numpy'])
908
 
909
  x_values = [x0]
910
  y_values = [f(x0)]
911
+ derivative_values = [f_prime(x0)]
912
+ second_derivative_values = [f_prime_prime(x0)]
913
 
914
  x = x0
915
  m = 0 # first moment
 
926
 
927
  x_values.append(x)
928
  y_values.append(f(x))
929
+ derivative_values.append(f_prime(x))
930
+ second_derivative_values.append(f_prime_prime(x))
931
 
932
  return {
933
  "x": x_values,
934
  "y": y_values,
935
+ "derivative": derivative_values,
936
+ "secondDerivative": second_derivative_values,
937
  }
938
 
939
 
 
950
  f = lambdify(('x', 'y'), function, modules=['numpy'])
951
  fx = lambdify(('x', 'y'), function.diff('x'), modules=['numpy'])
952
  fy = lambdify(('x', 'y'), function.diff('y'), modules=['numpy'])
953
+ fxx = lambdify(('x', 'y'), function.diff('x', 2), modules=['numpy'])
954
+ fyy = lambdify(('x', 'y'), function.diff('y', 2), modules=['numpy'])
955
+ fxy = lambdify(('x', 'y'), function.diff('x', 'y'), modules=['numpy'])
956
 
957
  x_values = [x0]
958
  y_values = [y0]
959
  z_values = [f(x0, y0)]
960
+ gradient_values = [_gradient_values(fx, fy, x0, y0)]
961
+ hessian_values = [_hessian_values(fxx, fxy, fyy, x0, y0)]
962
 
963
  x = x0
964
  y = y0
 
990
  x_values.append(x)
991
  y_values.append(y)
992
  z_values.append(f(x, y))
993
+ gradient_values.append(_gradient_values(fx, fy, x, y))
994
+ hessian_values.append(_hessian_values(fxx, fxy, fyy, x, y))
995
 
996
  return {
997
  "x": x_values,
998
  "y": y_values,
999
  "z": z_values,
1000
+ "gradient": gradient_values,
1001
+ "hessian": hessian_values,
1002
+ }
1003
+ `;const f="https://cdn.jsdelivr.net/pyodide/v0.26.1/full/pyodide.mjs";let e=null,a=null;async function r(){const{loadPyodide:n}=await import(f);e=await n({indexURL:"https://cdn.jsdelivr.net/pyodide/v0.26.1/full/"}),await e.loadPackage(["numpy","sympy"]),e.FS.writeFile("optimization_logic.py",l),e.FS.writeFile("optimization_manager.py",s),e.runPython("from optimization_manager import OptimizationManager; manager = OptimizationManager();"),a=e.globals.get("manager"),a||console.error("Failed to initialize optimization manager"),self.postMessage({type:"READY"})}function i(n){if(!n)return null;try{const t=n.toJs({dict_converter:Object.fromEntries});n.destroy&&n.destroy(),self.postMessage({type:"RESULT",data:t})}catch(t){console.error("Error handling Python result:",t)}}self.onmessage=async n=>{const t=n.data;if(!a){console.warn("Pyodide is not ready yet");return}switch(t.type){case"INIT":const o=e.toPy(t.settings);i(a.handle_update_settings(o));break;case"NEXT_STEP":i(a.handle_next_step());break;case"PREV_STEP":i(a.handle_prev_step());break;case"RESET":i(a.handle_reset());break;default:console.error("Unknown message type:",t);break}},r()})();
dist/index.html CHANGED
@@ -5,7 +5,7 @@
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>Optimization</title>
8
- <script type="module" crossorigin src="/assets/index-xwMlQNfu.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-DiNT9sUn.css">
10
  </head>
11
  <body>
 
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>Optimization</title>
8
+ <script type="module" crossorigin src="/assets/index-DOAl0ZPy.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-DiNT9sUn.css">
10
  </head>
11
  <body>
frontends/react/src/App.tsx CHANGED
@@ -63,6 +63,7 @@ export default function App() {
63
  settings={settingsUi}
64
  setSettings={handleSettingsUiChange}
65
  onRandomInitialPoint={handleRandomInitialPoint}
 
66
 
67
  onReset={() => api.sendReset()}
68
  onNextStep={() => api.sendNextStep()}
 
63
  settings={settingsUi}
64
  setSettings={handleSettingsUiChange}
65
  onRandomInitialPoint={handleRandomInitialPoint}
66
+ trajectoryValues={api.plotData.trajectoryValues}
67
 
68
  onReset={() => api.sendReset()}
69
  onNextStep={() => api.sendNextStep()}
frontends/react/src/OptimizationPlot.tsx CHANGED
@@ -16,10 +16,11 @@ export default function OptimizationPlot({ data, xlim, ylim, setAxisLimits }: Op
16
  let x: number[] = data.functionValues ? data.functionValues.x : [];
17
  let y: number[] = data.functionValues ? data.functionValues.y : [];
18
  let z: number[][] = data.functionValues && data.functionValues.z ? data.functionValues.z : [];
 
19
  let trajX: number[] = data.trajectoryValues ? data.trajectoryValues.x : [];
20
  let trajY: number[] = data.trajectoryValues ? data.trajectoryValues.y : [];
21
- let trajZ: number[][] = data.trajectoryValues && data.trajectoryValues.z ? data.trajectoryValues.z : [];
22
-
23
  const [colorScaleRange, setColorScaleRange] = useState<[number, number] | null>(null);
24
  const nextColorScaleRangeRef = useRef<[number, number] | null>(null);
25
 
 
16
  let x: number[] = data.functionValues ? data.functionValues.x : [];
17
  let y: number[] = data.functionValues ? data.functionValues.y : [];
18
  let z: number[][] = data.functionValues && data.functionValues.z ? data.functionValues.z : [];
19
+
20
  let trajX: number[] = data.trajectoryValues ? data.trajectoryValues.x : [];
21
  let trajY: number[] = data.trajectoryValues ? data.trajectoryValues.y : [];
22
+ let trajZ: number[] = data.trajectoryValues && data.trajectoryValues.z ? data.trajectoryValues.z : [];
23
+
24
  const [colorScaleRange, setColorScaleRange] = useState<[number, number] | null>(null);
25
  const nextColorScaleRangeRef = useRef<[number, number] | null>(null);
26
 
frontends/react/src/Sidebar.tsx CHANGED
@@ -4,7 +4,7 @@ import Tabs from "./ui/Tabs.tsx";
4
  import Dropdown from "./ui/Dropdown.tsx";
5
  import Button from "./ui/Button.tsx";
6
  import Radio from "./ui/Radio.tsx";
7
- import { SUPPORTED_MODES, SUPPORTED_ALGORITHMS, type SettingsUi } from "./types.ts";
8
 
9
 
10
  const DEFAULT_HYPERPARAMETERS = {
@@ -40,6 +40,7 @@ interface SidebarProps {
40
  settings: SettingsUi,
41
  setSettings: (settings: SettingsUi) => void,
42
  onRandomInitialPoint: () => void,
 
43
 
44
  onReset?: () => void,
45
  onNextStep?: () => void,
@@ -52,6 +53,7 @@ export default function Sidebar({
52
  settings,
53
  setSettings,
54
  onRandomInitialPoint,
 
55
  onReset,
56
  onNextStep,
57
  onPrevStep,
@@ -91,7 +93,21 @@ export default function Sidebar({
91
  setFunctionOption(newFunctionOption);
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
94
 
 
 
 
 
95
 
96
  return (
97
  <div className="bg-gray-100 flex flex-col h-full p-4 gap-2">
@@ -209,6 +225,59 @@ export default function Sidebar({
209
 
210
  {activeTab === "Optimize" && (
211
  <>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  <div className="grid grid-cols-2 gap-2">
213
  <Button label="Next Step" onClick={onNextStep}/ >
214
  <Button label="Previous Step" onClick={onPrevStep} />
 
4
  import Dropdown from "./ui/Dropdown.tsx";
5
  import Button from "./ui/Button.tsx";
6
  import Radio from "./ui/Radio.tsx";
7
+ import { SUPPORTED_MODES, SUPPORTED_ALGORITHMS, type SettingsUi, type TrajectoryValues } from "./types.ts";
8
 
9
 
10
  const DEFAULT_HYPERPARAMETERS = {
 
40
  settings: SettingsUi,
41
  setSettings: (settings: SettingsUi) => void,
42
  onRandomInitialPoint: () => void,
43
+ trajectoryValues?: TrajectoryValues | null,
44
 
45
  onReset?: () => void,
46
  onNextStep?: () => void,
 
53
  settings,
54
  setSettings,
55
  onRandomInitialPoint,
56
+ trajectoryValues,
57
  onReset,
58
  onNextStep,
59
  onPrevStep,
 
93
  setFunctionOption(newFunctionOption);
94
  }
95
 
96
+ function getLastValue<T>(values?: T[] | null): T | null {
97
+ return values && values.length > 0 ? values[values.length - 1] : null;
98
+ }
99
+
100
+ const currentX = getLastValue(trajectoryValues?.x);
101
+ const currentY = getLastValue(trajectoryValues?.y);
102
+
103
+ // univariate only
104
+ const currentDerivative = getLastValue(trajectoryValues?.derivative);
105
+ const currentSecondDerivative = getLastValue(trajectoryValues?.secondDerivative);
106
 
107
+ // bivariate only
108
+ const currentZ = getLastValue(trajectoryValues?.z);
109
+ const currentGradient = getLastValue(trajectoryValues?.gradient);
110
+ const currentHessian = getLastValue(trajectoryValues?.hessian);
111
 
112
  return (
113
  <div className="bg-gray-100 flex flex-col h-full p-4 gap-2">
 
225
 
226
  {activeTab === "Optimize" && (
227
  <>
228
+ { settings.mode === "Univariate" && (
229
+ <>
230
+ <InputField
231
+ label="Current X"
232
+ value={currentX !== null ? currentX.toFixed(4) : ""}
233
+ readonly
234
+ />
235
+ <InputField
236
+ label="Current Y"
237
+ value={currentY !== null ? currentY.toFixed(4) : ""}
238
+ readonly
239
+ />
240
+ <InputField
241
+ label="Current Derivative"
242
+ value={currentDerivative !== null ? currentDerivative.toFixed(4) : ""}
243
+ readonly
244
+ />
245
+ <InputField
246
+ label="Current Second Derivative"
247
+ value={currentSecondDerivative !== null ? currentSecondDerivative.toFixed(4) : ""}
248
+ readonly
249
+ />
250
+ </>
251
+ )}
252
+ { settings.mode === "Bivariate" && (
253
+ <>
254
+ <InputField
255
+ label="Current X"
256
+ value={currentX !== null ? currentX.toFixed(4) : ""}
257
+ readonly
258
+ />
259
+ <InputField
260
+ label="Current Y"
261
+ value={currentY !== null ? currentY.toFixed(4) : ""}
262
+ readonly
263
+ />
264
+ <InputField
265
+ label="Current Z"
266
+ value={currentZ !== null ? currentZ.toFixed(4) : ""}
267
+ readonly
268
+ />
269
+ <InputField
270
+ label="Current Gradient"
271
+ value={currentGradient !== null ? `[${currentGradient.map(v => v.toFixed(4)).join(", ")}]` : ""}
272
+ readonly
273
+ />
274
+ <InputField
275
+ label="Current Hessian"
276
+ value={currentHessian !== null ? `[${currentHessian.map(row => `[${row.map(v => v.toFixed(4)).join(", ")}]`).join(", ")}]` : ""}
277
+ readonly
278
+ />
279
+ </>
280
+ )}
281
  <div className="grid grid-cols-2 gap-2">
282
  <Button label="Next Step" onClick={onNextStep}/ >
283
  <Button label="Previous Step" onClick={onPrevStep} />
frontends/react/src/types.ts CHANGED
@@ -31,9 +31,23 @@ export type PlotValues = {
31
  z?: number[][];
32
  }
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  export type PlotData = {
35
  functionValues?: PlotValues;
36
- trajectoryValues?: PlotValues;
37
  }
38
 
39
  export const SUPPORTED_MODES = ["Univariate", "Bivariate"] as const;
 
31
  z?: number[][];
32
  }
33
 
34
+ export type TrajectoryValues = {
35
+ x: number[];
36
+ y: number[];
37
+
38
+ // univariate only
39
+ derivative?: number[];
40
+ secondDerivative?: number[];
41
+
42
+ // bivariate only
43
+ z?: number[];
44
+ gradient?: number[][];
45
+ hessian?: number[][][];
46
+ }
47
+
48
  export type PlotData = {
49
  functionValues?: PlotValues;
50
+ trajectoryValues?: TrajectoryValues;
51
  }
52
 
53
  export const SUPPORTED_MODES = ["Univariate", "Bivariate"] as const;