-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdemo_multivariate.py
More file actions
215 lines (170 loc) · 7.83 KB
/
demo_multivariate.py
File metadata and controls
215 lines (170 loc) · 7.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/env python3
"""
Demonstration of the multivariate derivatives functionality in pydelt.
This script shows how to use the MultivariateDerivatives class to compute
gradients, Jacobians, Hessians, and Laplacians for multivariate functions.
"""
import numpy as np
import matplotlib.pyplot as plt
from src.pydelt.multivariate import MultivariateDerivatives
from src.pydelt.interpolation import SplineInterpolator, LlaInterpolator
def main():
print("🚀 Multivariate Derivatives Demonstration")
print("=" * 50)
# Create test data for a 2D scalar function: f(x,y) = x^2 + y^2
print("\n1. Setting up test data...")
x = np.linspace(-2, 2, 20)
y = np.linspace(-2, 2, 20)
X, Y = np.meshgrid(x, y)
# Input data: (x, y) coordinates
input_data = np.column_stack([X.flatten(), Y.flatten()])
# Scalar function: f(x,y) = x^2 + y^2
scalar_output = (X**2 + Y**2).flatten()
# Vector function: [x^2 + y^2, x + y]
vector_output = np.column_stack([
(X**2 + Y**2).flatten(),
(X + Y).flatten()
])
print(f"Input shape: {input_data.shape}")
print(f"Scalar output shape: {scalar_output.shape}")
print(f"Vector output shape: {vector_output.shape}")
# Test with different interpolators
interpolators = [
("Spline", SplineInterpolator, {"smoothing": 0.1}),
("LLA", LlaInterpolator, {"window_size": 5})
]
for name, interp_class, kwargs in interpolators:
print(f"\n2. Testing with {name} Interpolator")
print("-" * 30)
# Initialize multivariate derivatives
mv = MultivariateDerivatives(interp_class, **kwargs)
mv.fit(input_data, scalar_output)
# Test point
test_point = np.array([[1.0, 1.0]])
print(f"Test point: {test_point[0]}")
# Compute gradient
gradient_func = mv.gradient()
grad = gradient_func(test_point)
print(f"Gradient: {grad.flatten()}")
print(f"Expected: [2.0, 2.0] (analytical: [2x, 2y])")
# Compute Hessian
hessian_func = mv.hessian()
hess = hessian_func(test_point)
print(f"Hessian diagonal: {np.diag(hess)}")
print(f"Expected: [2.0, 2.0] (analytical: [2, 2])")
# Compute Laplacian
laplacian_func = mv.laplacian()
lap = laplacian_func(test_point)
print(f"Laplacian: {lap.flatten()[0]:.4f}")
print(f"Expected: 4.0 (analytical: ∇²f = 2 + 2 = 4)")
# Now test with vector output
print("\n3. Testing with Vector Function")
print("-" * 30)
# Fit with vector output
mv.fit(input_data, vector_output)
# Compute Jacobian
jacobian_func = mv.jacobian()
jac = jacobian_func(test_point)
print(f"Jacobian at {test_point[0]}:")
print(jac[0])
print("Expected:")
print("[[2.0, 2.0], [1.0, 1.0]] (analytical: [[2x, 2y], [1, 1]])")
def visualize_results():
"""Create visualizations of multivariate derivatives"""
import plotly.graph_objects as go
from plotly.subplots import make_subplots
print("\n4. Creating visualization...")
# Create a finer grid for visualization
x = np.linspace(-2, 2, 50)
y = np.linspace(-2, 2, 50)
X, Y = np.meshgrid(x, y)
# Input data: (x, y) coordinates
input_data = np.column_stack([X.flatten(), Y.flatten()])
# Scalar function: f(x,y) = x^2 + y^2
scalar_output = (X**2 + Y**2).flatten()
# Initialize multivariate derivatives with SplineInterpolator
mv = MultivariateDerivatives(SplineInterpolator, smoothing=0.1)
mv.fit(input_data, scalar_output)
# Compute gradient and laplacian
gradient_func = mv.gradient()
laplacian_func = mv.laplacian()
# Evaluate on the grid
gradients = gradient_func(input_data)
laplacians = laplacian_func(input_data)
# Reshape for plotting
Z = scalar_output.reshape(X.shape)
grad_x = gradients[:, 0].reshape(X.shape)
grad_y = gradients[:, 1].reshape(X.shape)
lap = laplacians.reshape(X.shape)
# Create figure with subplots
fig = make_subplots(rows=2, cols=2,
subplot_titles=('Function f(x,y) = x² + y²',
'Gradient Magnitude ||∇f||',
'Gradient Vector Field',
'Laplacian ∇²f'),
specs=[[{'type': 'surface'}, {'type': 'surface'}],
[{'type': 'contour'}, {'type': 'contour'}]])
# Add surface plot of function
fig.add_trace(go.Surface(x=X, y=Y, z=Z, colorscale='Viridis',
name='f(x,y) = x² + y²'), row=1, col=1)
# Add surface plot of gradient magnitude
grad_mag = np.sqrt(grad_x**2 + grad_y**2)
fig.add_trace(go.Surface(x=X, y=Y, z=grad_mag, colorscale='Plasma',
name='||∇f||'), row=1, col=2)
# Add contour plot with gradient vector field
fig.add_trace(go.Contour(x=x, y=y, z=Z, colorscale='Viridis',
name='f(x,y)'), row=2, col=1)
# Add vector field (subsample for clarity)
skip = 4
fig.add_trace(go.Scatter(x=X[::skip, ::skip].flatten(),
y=Y[::skip, ::skip].flatten(),
mode='markers+text',
marker=dict(symbol='arrow', size=10,
angle=np.arctan2(grad_y[::skip, ::skip],
grad_x[::skip, ::skip]).flatten()*180/np.pi),
text='→', textposition='middle center',
name='∇f'), row=2, col=1)
# Add Laplacian contour plot
fig.add_trace(go.Contour(x=x, y=y, z=lap, colorscale='RdBu',
contours=dict(start=3.9, end=4.1, size=0.01),
name='∇²f'), row=2, col=2)
# Update layout
fig.update_layout(title_text='Multivariate Derivatives Visualization',
height=800, width=1000,
scene=dict(xaxis_title='x', yaxis_title='y', zaxis_title='f(x,y)'),
scene2=dict(xaxis_title='x', yaxis_title='y', zaxis_title='||∇f||'))
# Save to HTML file
fig.write_html('multivariate_derivatives_demo.html')
print("Visualization saved to 'multivariate_derivatives_demo.html'")
if __name__ == "__main__":
main()
try:
visualize_results()
except ImportError:
print("\nVisualization requires plotly. Install with: pip install plotly")
print(f"\n4. Multiple Point Evaluation")
print("-" * 30)
# Create test data again for this section
x = np.linspace(-2, 2, 20)
y = np.linspace(-2, 2, 20)
X, Y = np.meshgrid(x, y)
# Input data: (x, y) coordinates
grid_input_data = np.column_stack([X.flatten(), Y.flatten()])
# Scalar function: f(x,y) = x^2 + y^2
grid_scalar_output = (X**2 + Y**2).flatten()
# Test with multiple points
test_points = np.array([[0.0, 0.0], [1.0, 1.0], [2.0, 2.0]])
mv = MultivariateDerivatives(SplineInterpolator, smoothing=0.1)
mv.fit(grid_input_data, grid_scalar_output)
gradient_func = mv.gradient()
gradients = gradient_func(test_points)
print(f"Test points shape: {test_points.shape}")
print(f"Gradients shape: {gradients.shape}")
print("Gradients at multiple points:")
for i, (point, grad) in enumerate(zip(test_points, gradients)):
print(f" Point {point}: Gradient {grad}")
print(f"\n✅ Multivariate derivatives demonstration complete!")
print("The module successfully computes gradients, Jacobians, Hessians, and Laplacians")
print("for both scalar and vector-valued multivariate functions.")
if __name__ == "__main__":
main()