Re: Add terms surrounded by zero together in matrix

*To*: mathgroup at smc.vnet.net*Subject*: [mg59180] Re: Add terms surrounded by zero together in matrix*From*: Maxim <ab_def at prontomail.com>*Date*: Sun, 31 Jul 2005 01:30:50 -0400 (EDT)*References*: <dcccur$3j7$1@smc.vnet.net> <dcf34j$lf9$1@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

On Sat, 30 Jul 2005 05:27:47 +0000 (UTC), Paul Abbott <paul at physics.uwa.edu.au> wrote: > In article <dcccur$3j7$1 at smc.vnet.net>, > "mchangun at gmail.com" <mchangun at gmail.com> wrote: > >> I think this is a rather tough problem to solve. I'm stumped and would >> really appreciated it if someone can come up with a solution. >> >> What i want to do is this. Suppose i have the following matrix: >> >> 0 0 0 1 0 >> 0 0 1 2 0 >> 0 0 0 2 1 >> 1 3 0 0 0 >> 0 0 0 0 0 >> 0 0 0 0 0 >> 0 0 1 1 0 >> 5 0 3 0 0 >> 0 0 0 0 0 >> 0 0 0 3 1 >> >> I'd like to go through it and sum the elements which are surrounded by >> zeros. So for the above case, an output: >> >> [7 4 5 5 4] >> >> is required. The order in which the groups surrounded by zero is >> summed does not matter. >> >> The elements are always integers greater than 0. > > Have a look at the literature on percolation clusters and in the > MathGroup archive. > > I would have thought that you could use > > << Statistics`ClusterAnalysis` > > to solve this, but I could not get it to work right. The basic idea I > had was to locate the non-zero entries in > > dat = {{0, 0, 0, 1, 0}, {0, 0, 1, 2, 0}, {0, 0, 0, 2, 1}, > {1, 3, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, > {0, 0, 1, 1, 0}, {5, 0, 3, 0, 0}, {0, 0, 0, 0, 0}, > {0, 0, 0, 3, 1}}; > > using Position: > > pos = Position[dat, n_Integer /; n > 0] > > and then apply FindClusters to these positions. For example, > > cl = FindClusters[pos, DistanceFunction -> BrayCurtisDistance] > > gives 3 clusters (I tried other distance metrics and several of the > myriad of options to FindClusters to try to get FindClusters to only > find "connected" clusters). From these clusters, > > Extract[dat, #] & /@ cl > > gets the values in each cluster, and > > Total /@ % > > gives the totals for each cluster. Maybe others can see how to improve > on this -- or explain why this approach cannot work. > > Cheers, > Paul > This can be done as follows: In[1]:= <<statistics` dat = {{0, 0, 0, 1, 0}, {0, 0, 1, 2, 0}, {0, 0, 0, 2, 1}, {1, 3, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 1, 1, 0}, {5, 0, 3, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 3, 1}}; pos = Position[dat, n_Integer /; n > 0]; cl = FindClusters[pos, DistanceFunction -> (Boole[Norm[# - #2, 1] != 1]&), Method -> Agglomerate]; Total /@ (Extract[dat, #]&) /@ cl Out[5]= {7, 4, 5, 5, 4} But this algorithm is heuristic in nature and might not give correct results. Another way is to think of the problem in terms of operations on graphs: In[6]:= <<discretemath` Module[{L, LL}, L = Position[dat, a_ /; a != 0, {2}, Heads -> False]; LL = Flatten@Position[L, {x_, y_} /; Norm[{x, y} - #, 1] == 1, {1}, Heads -> False]& /@ L; LL = ConnectedComponents[FromAdjacencyLists[LL]]; Total@Extract[dat, L[[#]]]& /@ LL ] Out[7]= {7, 4, 5, 5, 4} This assumes that the groups should be 4-connected. Maxim Rytin m.r at inbox.ru