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

Added Sidef
(Added Lua)
(Added Sidef)
 
(7 intermediate revisions by 5 users not shown)
Line 96:
[[ 0 0 0 0 1 ][ 0 0 0 1 0 ][ 0 0 1 0 0 ][ 0 1 0 0 0 ]] -> [ 0 0.25 0.25 0.25 0.25 ]
</pre>
 
=={{header|ALGOL W}}==
<syntaxhighlight lang="algolw">
begin % find the centroid of some N dimensional points %
 
% sets cPoints to the centroid of points %
procedure centroid( real array points ( *, * )
; integer value numberOfPoints, dimension
; real array cPoint ( * )
) ;
for j := 1 until dimension do begin
real sum;
sum := 0;
for i := 1 until numberOfpoints do sum := sum + points( i, j );
cPoint( j ) := sum / numberOfPoints
end centroid ;
 
begin % task test cases %
 
% show a real number with two decimal places if if is not integral %
procedure show ( real value rValue ) ;
begin
integer iValue;
iValue := truncate( rValue );
if iValue = rValue then writeon( s_w := 0, i_w := 1, " ", iValue )
else writeon( s_w := 0
, r_format := "A", r_w := 4, r_d := 2
, " ", rValue
)
end show ;
 
procedure testCentroid( real array points ( *, * )
; integer value numberOfPoints, dimension
) ;
begin
real array cPoint( 1 :: dimension );
centroid( points, numberOfPoints, dimension, cPoint );
write( "[" );
for i := 1 until numberOfPoints do begin
writeon( "[" );
for j := 1 until dimension do show( points( i, j ) );
writeon( " ]" );
end for_i ;
writeon( "] -> [" );
for j := 1 until dimension do show( cPoint( j ) );
writeon( " ]" )
end testCentroid ;
 
real array p1 ( 1 :: 3, 1 :: 1 ); real array p2 ( 1 :: 2, 1 :: 2 );
real array p3 ( 1 :: 2, 1 :: 3 ); real array p4 ( 1 :: 4, 1 :: 3 );
real array p5 ( 1 :: 4, 1 :: 5 );
 
p1( 1, 1 ) := 1; p1( 2, 1 ) := 2; p1( 3, 1 ) := 3;
p2( 1, 1 ) := 8; p2( 1, 2 ) := 2;
p2( 2, 1 ) := 0; p2( 2, 2 ) := 0;
p3( 1, 1 ) := 5; p3( 1, 2 ) := 5; p3( 1, 3 ) := 0;
p3( 2, 1 ) := 10; p3( 2, 2 ) := 10; p3( 2, 3 ) := 0;
p4( 1, 1 ) := 1; p4( 1, 2 ) := 3.1; p4( 1, 3 ) := 6.5;
p4( 2, 1 ) := -2; p4( 2, 2 ) := -5; p4( 2, 3 ) := 3.4;
p4( 3, 1 ) := -7; p4( 3, 2 ) := -4; p4( 3, 3 ) := 9;
p4( 4, 1 ) := 2; p4( 4, 2 ) := 0; p4( 4, 3 ) := 3;
p5( 1, 1 ) := 0; p5( 1, 2 ) := 0; p5( 1, 3 ) := 0; p5( 1, 4 ) := 0; p5( 1, 5 ) := 1;
p5( 2, 1 ) := 0; p5( 2, 2 ) := 0; p5( 2, 3 ) := 0; p5( 2, 4 ) := 1; p5( 2, 5 ) := 0;
p5( 3, 1 ) := 0; p5( 3, 2 ) := 0; p5( 3, 3 ) := 1; p5( 3, 4 ) := 0; p5( 3, 5 ) := 0;
p5( 4, 1 ) := 0; p5( 4, 2 ) := 1; p5( 4, 3 ) := 0; p5( 4, 4 ) := 0; p5( 4, 5 ) := 0;
 
testCentroid( p1, 3, 1 );
testCentroid( p2, 2, 2 );
testCentroid( p3, 2, 3 );
testCentroid( p4, 4, 3 );
testCentroid( p5, 4, 5 )
 
end
 
end.</syntaxhighlight>
{{out}}
<pre>[[ 1 ][ 2 ][ 3 ]] -> [ 2 ]
[[ 8 2 ][ 0 0 ]] -> [ 4 1 ]
[[ 5 5 0 ][ 10 10 0 ]] -> [ 7.50 7.50 0 ]
[[ 1 3.10 6.50 ][ -2 -5 3.40 ][ -7 -4 9 ][ 2 0 3 ]] -> [ -1.50 -1.47 5.47 ]
[[ 0 0 0 0 1 ][ 0 0 0 1 0 ][ 0 0 1 0 0 ][ 0 1 0 0 0 ]] -> [ 0 0.25 0.25 0.25 0.25 ]</pre>
 
=={{header|BASIC256}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">subroutine Centroid(n, d, pts)
dim ctr(d)
 
for j = 0 to d-1
ctr[j] = 0
for i = 0 to n-1
ctr[j] += pts[i,j]
next
ctr[j] /= n
next
print "{";
for i = 0 to n-1
print "{";
for j = 0 to d-1
print pts[i,j];
if j < d-1 then print ", ";
next
print "}";
if i < n-1 then print ", ";
next
print "} => Centroid: {";
for j = 0 to d-1
print ctr[j];
if j < d-1 then print ", ";
next
print "}"
end subroutine
 
pts1 = {{1}, {2}, {3}}
pts2 = {{8, 2}, {0, 0}}
pts3 = {{5, 5, 0}, {10, 10, 0}}
pts4 = {{1, 3.1, 6.5}, {-2, -5, 3.4}, {-7, -4, 9}, {2, 0, 3}}
pts5 = {{0, 0, 0, 0, 1}, {0, 0, 0, 1, 0}, {0, 0, 1, 0, 0}, {0, 1, 0, 0, 0}}
 
call Centroid(3, 1, pts1)
call Centroid(2, 2, pts2)
call Centroid(2, 3, pts3)
call Centroid(4, 3, pts4)
call Centroid(4, 5, pts5)
end</syntaxhighlight>
{{out}}
<pre>Similar to FreeBASIC entry.</pre>
 
=={{header|C}}==
Line 152 ⟶ 278:
{{0, 0, 0, 0, 1}, {0, 0, 0, 1, 0}, {0, 0, 1, 0, 0}, {0, 1, 0, 0, 0}} => Centroid: {0, 0.25, 0.25, 0.25, 0.25}
</pre>
 
=={{header|FreeBASIC}}==
{{trans|XPL0}}
<syntaxhighlight lang="vb">Sub Centroid(n As Ubyte, d As Ubyte, pts() As Single)
Dim As Ubyte i, j
Dim As Single ctr(d)
For j = 0 To d-1
ctr(j) = 0
For i = 0 To n-1
ctr(j)+ = pts(i,j)
Next
ctr(j) /= n
Next
Print "{";
For i = 0 To n-1
Print "{";
For j = 0 To d-1
Print Using "&"; pts(i,j);
If j < d-1 Then Print ", ";
Next
Print "}";
If i < n-1 Then Print ", ";
Next
Print "} => Centroid: {";
For j = 0 To d-1
Print Using "&"; ctr(j);
If j < d-1 Then Print ", ";
Next
Print "}"
End Sub
 
Dim pts1(2, 1) As Single = {{1}, {2}, {3}}
Dim pts2(1, 1) As Single = {{8, 2}, {0, 0}}
Dim pts3(1, 2) As Single = {{5, 5, 0}, {10, 10, 0}}
Dim pts4(3, 2) As Single = {{1, 3.1, 6.5}, {-2, -5, 3.4}, {-7, -4, 9}, {2, 0, 3}}
Dim pts5(3, 4) As Single = {{0, 0, 0, 0, 1}, _
{0, 0, 0, 1, 0}, {0, 0, 1, 0, 0}, {0, 1, 0, 0, 0}}
 
Centroid(3, 1, pts1())
Centroid(2, 2, pts2())
Centroid(2, 3, pts3())
Centroid(4, 3, pts4())
Centroid(4, 5, pts5())
 
Sleep</syntaxhighlight>
{{out}}
<pre>{{1}, {2}, {3}} => Centroid: {2}
{{8, 2}, {0, 0}} => Centroid: {4, 1}
{{5, 5, 0}, {10, 10, 0}} => Centroid: {7.5, 7.5, 0}
{{1, 3.1, 6.5}, {-2, -5, 3.4}, {-7, -4, 9}, {2, 0, 3}} => Centroid: {-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}} => Centroid: {0, 0.25, 0.25, 0.25, 0.25}</pre>
 
=={{header|Go}}==
Line 205 ⟶ 383:
[[0 0 0 0 1] [0 0 0 1 0] [0 0 1 0 0] [0 1 0 0 0]] => Centroid: [0 0.25 0.25 0.25 0.25]
</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq.'''
 
With a trivial change to the last line (the one using string interpolation), the following also works with jaq, the Rust implementation of jq.
<syntaxhighlight lang="jq">
# Input: an array of points of the same dimension (i.e. numeric arrays of the same length)
def centroid:
length as $n
| if ($n == 0) then "centroid: list must contain at least one point." | error else . end
| (.[0]|length) as $d
| if any( .[]; length != $d )
then "centroid: points must all have the same dimension." | error
else .
end
| transpose
| map( add / $n ) ;
 
def points: [
[ [1], [2], [3] ],
[ [8, 2], [0, 0] ],
[ [5, 5, 0], [10, 10, 0] ],
[ [1, 3.1, 6.5], [-2, -5, 3.4], [-7, -4, 9], [2, 0, 3] ],
[ [0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 0, 0] ]
];
 
points[]
| "\(.) => Centroid: \(centroid)"
</syntaxhighlight>
{{output}}
Essentially as for [[#Wren|Wren]].
 
=={{header|Julia}}==
Line 318 ⟶ 528:
 
=={{header|Perl}}==
===PDL library, with plot===
{{libheader|PDL}}
<syntaxhighlight lang="perl">use v5.36;
Line 359 ⟶ 570:
[0 0.25 0.25 0.25 0.25]</pre>
[[File:Centroid_plot_perl.png|center|thumb]]
===Direct calculation===
<syntaxhighlight lang="perl" line>
use v5.36;
 
sub centroid ($LoL) {
my $n = $#{ $LoL };
my $d = $#{ $LoL->@[0] };
my @C = 0 x ($d+1);
for my $i (0..$d) {
$C[$i] += $LoL->@[$_]->@[$i] for 0..$n;
$C[$i] /= $n+1
}
@C
}
 
say join ' ', centroid($_) for
[ [1,], [2,], [3,] ],
[ [8, 2], [0, 0] ],
[ [5, 5, 0], [10, 10, 0] ],
[ [1, 3.1, 6.5], [-2, -5, 3.4], [-7, -4, 9], [2, 0, 3] ],
[ [0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 0, 0] ];
</syntaxhighlight>
{{out}}
<pre>
2
4 1
7.5 7.5 0
-1.5 -1.475 5.475
0 0.25 0.25 0.25 0.25
</pre>
 
=={{header|Phix}}==
Line 402 ⟶ 643:
(-1.5 -1.475 5.475)
(0 0.25 0.25 0.25 0.25)</pre>
 
=={{header|Sidef}}==
 
<syntaxhighlight lang="ruby">func centroid(l) {
l.combine {|*a| a.sum } »/» l.len
}
 
[
[ [1], [2], [3] ],
[ [8, 2], [0, 0] ],
[ [5, 5, 0], [10, 10, 0] ],
[ [1, 3.1, 6.5], [-2, -5, 3.4], [-7, -4, 9], [2, 0, 3] ],
[ [0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 0, 0] ],
].each {
say centroid(_)
}</syntaxhighlight>
 
{{out}}
<pre>
[2]
[4, 1]
[15/2, 15/2, 0]
[-3/2, -59/40, 219/40]
[0, 1/4, 1/4, 1/4, 1/4]
</pre>
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">var centroid = Fn.new { |pts|
var n = pts.count
if (n == 0) Fiber.abort("List must contain at least one point.")
Line 445 ⟶ 711:
{{libheader|Wren-math}}
Or, more concise using library methods - output identical.
<syntaxhighlight lang="ecmascriptwren">import "./seq" for Lst
import "./math" for Nums
 
2,747

edits