Is there a built-in function to get the centroid of a table? - Mathematica Stack Exchange most recent 30 from mathematica.stackexchange.com 2019-09-21T20:25:11Z https://mathematica.stackexchange.com/feeds/question/177109 https://creativecommons.org/licenses/by-sa/4.0/rdf https://mathematica.stackexchange.com/q/177109 7 Is there a built-in function to get the centroid of a table? Emilio Pisanty https://mathematica.stackexchange.com/users/1000 2018-07-11T11:58:04Z 2018-07-11T18:45:25Z <p>Suppose I have a table with some data that are 'lumped' around some central location, such as the dummy example</p> <pre><code>i0 = 22.3; j0 = 34.1; table = Table[ Exp[-((i - i0)^2 + (j - j0)^2)/10^2] , {i, 1, 50}, {j, 1, 50} ] </code></pre> <p>which kind of looks like</p> <pre><code>ListPointPlot3D[table, PlotRange -&gt; Full] </code></pre> <p><img src="https://i.stack.imgur.com/oz86i.png" alt="Mathematica graphics"></p> <p><strong>I would like to recover the centroid of the "mass" determined by the signal in my table</strong>, i.e. in the case above, the tuplet <code>{i0,j0}</code>, in the cleanest way possible. I've managed to do it in the obvious but expensive way with a bunch of explicit sums and products with explicit <code>Range</code>s, but it feels like there should be a built-in function that will do this ─ and I've as yet been unable to find it.</p> <p>Can this be done? If so, how?</p> https://mathematica.stackexchange.com/questions/177109/-/177110#177110 11 Answer by kglr for Is there a built-in function to get the centroid of a table? kglr https://mathematica.stackexchange.com/users/125 2018-07-11T12:10:46Z 2018-07-11T13:13:11Z <pre><code>wd = WeightedData[Tuples @ Range @ Dimensions @ table, Join @@ table] Mean @ wd </code></pre> <blockquote> <p>{22.3232, 33.9072}</p> </blockquote> <p>Also</p> <pre><code>Total[MapIndexed[#2 # &amp;, table / Total[table, 2], {2}], 2] (* and *) Dot[Join @@ table , Tuples[Range @ Dimensions @ table]] / Total[table, 2] </code></pre> <blockquote> <p>{22.3232, 33.9072}</p> </blockquote> https://mathematica.stackexchange.com/questions/177109/-/177111#177111 8 Answer by Szabolcs for Is there a built-in function to get the centroid of a table? Szabolcs https://mathematica.stackexchange.com/users/12 2018-07-11T12:12:49Z 2018-07-11T12:12:49Z <pre><code>i0 = 22.3; j0 = 34.1; table = Table[ Exp[-((i - i0)^2 + (j - j0)^2)/10^2], {i, 1, 50}, {j, 1, 50}]; x = Array[#1 &amp;, Dimensions[table]]; y = Array[#2 &amp;, Dimensions[table]]; pt = {Total@Flatten[x table], Total@Flatten[y table]}/ Total[table, 2] (* {22.3232, 33.9072} *) ListDensityPlot[table, Epilog -&gt; {Red, Point@Reverse[pt]}, PlotRange -&gt; All] </code></pre> <p><a href="https://i.stack.imgur.com/xiZ48.png" rel="noreferrer"><img src="https://i.stack.imgur.com/xiZ48.png" alt="enter image description here"></a></p> https://mathematica.stackexchange.com/questions/177109/-/177145#177145 6 Answer by Henrik Schumacher for Is there a built-in function to get the centroid of a table? Henrik Schumacher https://mathematica.stackexchange.com/users/38178 2018-07-11T18:45:25Z 2018-07-11T18:45:25Z <p>I can provide some improvement if it is about speed.</p> <p>Let's generate a larger data set (I use <code>Compile</code> merely to speed it up a bit).</p> <pre><code>i0 = 22.3; j0 = 34.1; m = 2500; n = 1500; x = Subdivide[1., 50, m - 1]; y = Subdivide[1., 50, n - 1]; table2 = Partition[#, n] &amp;@ Compile[{{X, _Real, 1}, {i0, _Real}, {j0, _Real}}, Exp[-((X[] - i0)^2 + (X[] - j0)^2)/10^2], RuntimeAttributes -&gt; {Listable} ][Tuples[{x, y}], i0, j0]; </code></pre> <p>Szabolcs' approach</p> <pre><code>AbsoluteTiming[ pt = { Total@Flatten[Transpose[ConstantArray[x, n]] table], Total@Flatten[ConstantArray[y, m] table] }/Total[table, 2] ] </code></pre> <blockquote> <p>{0.733425, {22.3288, 33.8733}}</p> </blockquote> <p>The problem is that before summation, some large arrays have to be constructed and multiplied. But the summations and matrix-matrix products can also be expressed by cheaper matrix-vector products:</p> <pre><code>AbsoluteTiming[ pt2 = With[{buffer = ConstantArray[1., m].table}, {x.(table.ConstantArray[1., n]), buffer.y }/(ConstantArray[1., n].buffer) ] ] </code></pre> <blockquote> <p>{0.044209, {22.3288, 33.8733}}</p> </blockquote>