# What is the best way to calculate the numerical gradient of a matrix, representing multiple points in 3D space?

**URL:** <https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727>\
**Category:** Numerics\
**Tags:** question\
**Created:** [March 28, 2023, 8:47pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727 "2023-03-28T20:47:15Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dale\_James\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dale_james_black/32/11595_2.png) [@Dale\_James\_Black](https://discourse.julialang.org/u/Dale_James_Black)\
**Post date:** [March 28, 2023, 8:47pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/1 "2023-03-28T20:47:15Z")

</div>

Given a matrix, where each row represents a point in 3D space and each column represents the x, y, and z location. What is the recommended way to calculate the gradient at each point (at each row)?

```julia
points = [
    202 279 8
    202 280 9
    209 278 10
    210 283 12
    212 286 14
    219 295 16
    225 300 18
    234 308 20
    238 305 22
    236 300 24
    233 295 26
    231 289 28
    227 280 30
    223 275 31
]

```

---

<div class="post-metadata">

**Author:** ![Dale\_James\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dale_james_black/32/11595_2.png) [@Dale\_James\_Black](https://discourse.julialang.org/u/Dale_James_Black)\
**Post date:** [March 28, 2023, 8:48pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/2 "2023-03-28T20:48:03Z")

</div>

I haven’t verified it, but I am assuming `diff()` works. If so, is this the recommended approach? Maybe `imgradients()` from Images.jl?

---

<div class="post-metadata">

**Author:** ![Dale\_James\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dale_james_black/32/11595_2.png) [@Dale\_James\_Black](https://discourse.julialang.org/u/Dale_James_Black)\
**Post date:** [March 28, 2023, 9:15pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/3 "2023-03-28T21:15:00Z")

</div>

Here is a simple working example I came up with

```julia
function centraldiff(p1, p2, p3)
	u = p3 - p2
	v = p2 - p1
	return (u - v) ./ (norm(p3 - p1))
end

```

```julia
function gradients(points)
	grads = zeros(size(points))
	for i in axes(points, 1)
		if i == 1
			grads[i, :] = centraldiff(points[i, :], points[i, :], points[i+1, :])
		elseif i == size(points, 1)
			grads[i, :] = centraldiff(points[i-1, :], points[i, :], points[i, :])
		else
			grads[i, :] = centraldiff(points[i-1, :], points[i, :], points[i+1, :])
		end
	end
	return grads
end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 28, 2023, 9:15pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/4 "2023-03-28T21:15:20Z")

</div>

I’m not sure if the concept of ‘gradient’ makes any sense in this context. If `points` is just a list of positions, what are you taking the grafient _of_?

The gradient should represent the rate of change of a function or field _with respect_ to position. But you just have the positions, not the ‘thing’ of which you should find the gradient.

The rate of change of positions with respect to position should just be constant.

---

<div class="post-metadata">

**Author:** ![Dale\_James\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dale_james_black/32/11595_2.png) [@Dale\_James\_Black](https://discourse.julialang.org/u/Dale_James_Black)\
**Post date:** [March 28, 2023, 9:16pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/5 "2023-03-28T21:16:39Z")

</div>

I guess central difference is a more accurate name. Essentially `numpy.gradient`  
[https://numpy.org/doc/stable/reference/generated/numpy.gradient.html](https://numpy.org/doc/stable/reference/generated/numpy.gradient.html)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 28, 2023, 9:17pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/6 "2023-03-28T21:17:33Z")

</div>

That’s a scheme for estimating the gradient. But what are you taking the gradient _of_? I mean, where are the data whose sample points you have provided?

---

<div class="post-metadata">

**Author:** ![Dale\_James\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dale_james_black/32/11595_2.png) [@Dale\_James\_Black](https://discourse.julialang.org/u/Dale_James_Black)\
**Post date:** [March 28, 2023, 9:25pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/7 "2023-03-28T21:25:51Z")

</div>

They form a curve in 3D space

---

<div class="post-metadata">

**Author:** ![Dale\_James\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dale_james_black/32/11595_2.png) [@Dale\_James\_Black](https://discourse.julialang.org/u/Dale_James_Black)\
**Post date:** [March 28, 2023, 9:27pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/8 "2023-03-28T21:27:59Z")

</div>

Something like this in Makie

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/2/d2a77ba53deb2ac21949f431687a74202e1bb1bd.png)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 28, 2023, 9:38pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/9 "2023-03-28T21:38:21Z")

</div>

Gradients are for functions of multiple variables, but you have a 3D curve parameterized by a single variable.

You can use `diff` for this, sure.

---

<div class="post-metadata">

**Author:** ![Dale\_James\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dale_james_black/32/11595_2.png) [@Dale\_James\_Black](https://discourse.julialang.org/u/Dale_James_Black)\
**Post date:** [March 28, 2023, 9:51pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/10 "2023-03-28T21:51:43Z")

</div>

If that’s the case then this is probably the simplest answer (modified from [this](https://discourse.julialang.org/t/is-there-a-central-difference-gradient-function-somewhere/19454/3))

```julia
function central_difference(v::AbstractMatrix)
    dv = diff(v, dims=1) / 2
    a = [dv[[1], :]; dv]
    a .+= [dv; dv[[end], :]]
    a
end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 28, 2023, 10:04pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-calculate-the-numerical-gradient-of-a-matrix-representing-multiple-points-in-3d-space/96727/11 "2023-03-28T22:04:10Z")

</div>

That looks _very_ inefficient, allocating multiple arrays where only one should be needed. (Sorry, it’s too late for me to suggest a fix now, from my phone, but I suggest an array comprehension, or pre-allocate + loop. This is one example where Matlab-style vectorization is very suboptimal.)
