Higher dimensions

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()