Higher dimensions#
Finite difference generalizes readily to multiple dimensions, by computing the elements of the gradient individually:
\[
\frac{\partial f}{\partial x_i} ≈ \frac{f(x + heᵢ) - f(x - heᵢ)} {2h} \]
Boundary cases are handelled similarly but with the bounded dimension calculated by forward / backward difference.
# prompt: Give me an example of an ugly 2D function, plot it as a surface in plotly and show its gradients in arrows
import numpy as np
import plotly.graph_objects as go
import plotly.figure_factory as ff
# Define the function
def ugly_function(x, y):
return (np.sin(x) * np.cos(y) + np.cos(x) * np.sin(y)) * np.exp(-(x**2 + y**2) / 10)
# Create a grid of x and y values
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)
# Calculate the function values and gradients
Z = ugly_function(X, Y)
dZdx, dZdy = np.gradient(Z)
# Create the surface plot
fig = go.Figure(data=[go.Surface(z=Z, x=X, y=Y)])
fig.update_layout(title='Ugly 2D Function', autosize=False,
width=500, height=500,
margin=dict(l=65, r=50, b=65, t=90))
# Add gradient arrows to the plot
arrow_x = X[::5, ::5].flatten()
arrow_y = Y[::5, ::5].flatten()
arrow_z = Z[::5, ::5].flatten()
arrow_u = dZdx[::5, ::5].flatten()
arrow_v = dZdy[::5, ::5].flatten()
fig.add_trace(go.Cone(
x=arrow_x,
y=arrow_y,
z=arrow_z,
u=arrow_u,
v=arrow_v,
w=np.zeros_like(arrow_u),
sizemode="absolute",
sizeref=0.1,
showscale=False,
colorscale='Blues'
))
fig.show()