Centroid of a set of N-dimensional points: Difference between revisions

julia example
m (gr)
(julia example)
Line 26:
;; [[https://en.wikipedia.org/wiki/Centroid Wikipedia page]]
;; [[https://mathworld.wolfram.com/GeometricCentroid.html Wolfram Mathworld on Centroid]]
 
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Plots
 
struct Point{T, N}
v::Vector{T}
end
 
function centroid(points::Vector{Point{T, N}}) where N where T
arr = zeros(T, N)
for p in points, (i, x) in enumerate(p.v)
arr[i] += x
end
return Point{T, N}(sum.(arr) / length(points))
end
 
function centroid(arr)
isempty(arr)
n = length(arr[begin])
t = typeof(arr[begin][begin])
return centroid([Point{t, n}(v) for v in arr])
end
 
const testvecs = [[[1], [2], [3]],
[(8, 2), (0, 0)],
[[5, 5, 0], [10, 10, 0]],
[[1.0, 3.1, 6.5], [-2, -5, 3.4], [-7, -4, 9.0], [2.0, 0.0, 3.0],],
[[0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 0, 0],],
]
 
function test_centroids(tests)
for t in tests
isempty(t) && error("The empty set of points $t has no centroid")
vvec = [Point{Float64, length(t[begin])}(collect(v)) for v in t]
println("$t => $(centroid(vvec))")
end
xyz = [p[1] for p in testvecs[4]], [p[2] for p in testvecs[4]], [p[3] for p in testvecs[4]]
cpoint = centroid(testvecs[4]).v
for i in eachindex(cpoint)
push!(xyz[i], cpoint[i])
end
scatter(xyz..., color = [:navy, :navy, :navy, :navy, :red], legend = :none)
end
 
test_centroids(testvecs)
</syntaxhighlight>{{out}}
<pre>
[[1], [2], [3]] => Point{Float64, 1}([2.0])
[(8, 2), (0, 0)] => Point{Float64, 2}([4.0, 1.0])
[[5, 5, 0], [10, 10, 0]] => Point{Float64, 3}([7.5, 7.5, 0.0])
[[1.0, 3.1, 6.5], [-2.0, -5.0, 3.4], [-7.0, -4.0, 9.0], [2.0, 0.0, 3.0]] => Point{Float64, 3}([-1.5, -1.475, 5.475])
[[0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 0, 0]] => Point{Float64, 5}([0.0, 0.25, 0.25, 0.25, 0.25])
</pre>
[[File:Plot centroid.png|center|thumb]]
4,102

edits