wasnt able to figure out an array solution yet,
reverting to SymPy library I got this code to retrieve a list of
dx, dy at point x,y given your function:
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
xx = -3
yy = -2.54
funz = FunZ('x * y ** 2 * (sin(pi * x) + cos(2 * pi * y))')
# print('evalu : ',funz.evalu(xx,yy))
print(
funz.evalu(xx,yy), type(funz.evalu(xx,yy)),'\n',
funz.derX(xx, yy), type(funz.derX(xx, yy)),'\n',
funz.derY(xx, yy), type(funz.derY(xx, yy)),'\n'
)
print('_________________')
print(funz.derXY(xx,yy), type(funz.derXY(xx, yy)))
output:
18.74673336701243 <class 'float'>
54.55598636936226 <class 'float'>
15.481918816962425 <class 'float'>
_________________
[54.55598636936226, 15.481918816962425] <class 'list'>
not sure code is right, got it visualized throught:
import numpy as np
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
import matplotlib.pyplot as plt
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
XX = np.linspace(-3, 3, 100)
YY = np.linspace(-3, 3, 100)
funz = FunZ('x * y ** 2 * (sin(pi * x) + cos(2 * pi * y))')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
# print(arr, arr.size, arr.shape, arr.dtype)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
# print(derX, derX.size, derX.shape, derX.dtype)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
# print(derY, derY.size, derY.shape, derY.dtype)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(221, projection="3d")
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
ax2 = fig.add_subplot(223, projection="3d")
ax2.plot_trisurf(
x, y, derX[:, 2], color="blue", alpha=0.2)
ax3 = fig.add_subplot(224, projection="3d")
ax3.plot_trisurf(
x, y, derY[:, 2], color="green", alpha=0.2)
plt.show()
output is:

the code, especially the latter is very very slow, so I would be interested in a faster solution too, but given my poor knowlegde of python I can only wait for suggestions