For a computer program, given an nxn grid of scalar values (which can be viewed as a height field), I need to calculate the gradient at a point P therein, by sampling the 3x3 cells around P (its local cell neighbourhood).
To my rather naive thinking (calculus not being my strong point!), the below method should suffice: I take the average delta of each row (x) and each col (y) of the 3x3 neighbourhood:
0 x ->
y 4 1 0 1-4=-3, 0-1=-1, avg=-2.0
| 7 6 2 6-7=-1, 2-6=-4, avg=-2.5
V 9 8 5 8-9=-1, 5-8=-3, avg=-2.0
| | |
| | \- 2-0=+2, 5-2=+3, avg=+2.5
| \--- 6-1=+5, 8-6=+2, avg=+3.5
\----- 7-4=+3, 9-7=+2, avg=+2.5
Then I average these averages for x and y respectively (I could apply weighting to e.g. central row or column):
dx = (-2.0) + (-2.5) + (-2.0) = 6.5 / 3 = approx -2.17
dy = ( 2.5) + ( 3.5) + ( 2.5) = 8.5 / 3 = approx 2.83
So the resultant gradient ascent vector is (-2.17, 2.83).
Besides averaging across a larger neighbourhood (5x5, 7x7 etc.), are there other / better / more precise ways?
In fact your evaluation is equal at each point to
$$\frac{\partial f}{\partial x}=\frac{f(x+h)-f(x-h)}{2}$$ with obvious notations and a similar computation for the other partial derivative. This is a good evaluation.
However, at each step you’re adding $f(x)$ and subtracting it, which is not efficient in term of computation.