# How to measure the degree of concentration for a matrix

A normal image(from nature) have a smooth transition.Then we can use ImageCooccurrence to get a matrix(whose sum of all the elements is 1) like

img = ExampleData[{"TestImage", "Lena"}];
MatrixPlot[mat=ImageCooccurrence[img, 100]]


As we see,the mat have a good degree of concentration on the diagonal.But if you just use img = RandomImage[] to get a random image.you cannot get such result.It will be

My question is how to measure the degree of concentration of a matrix?

For example,this matrix: $$\left( \begin{array}{ccc} 0.5 & 0 & 0 \\ 0 & 0.2 & 0 \\ 0 & 0 & 0.3 \\ \end{array} \right)$$ I think its have a degree of concentration is 1.And this matrix: $$\left( \begin{array}{ccc} 0 & 0 & 0 \\ 0 & 0 & 0 \\ 0 & 0 & 0 \\ \end{array} \right)$$ I think its have a degree of concentration on the diagonal is 0. Is a good solution can do this?

• …I think this isn't a Mathematica problem? You're looking for a criterion judging the degree of concentration, I think you should ask this in math.stackexchange.com or scicomp.stackexchange.com ? Aug 9 '17 at 2:27
• @xzczd Wow,indeed,but it is produce in MMA.if other think as you think I will transform it to that site.Thanks. :)
– yode
Aug 9 '17 at 2:30
• As @xzczd says, this isn't a Mathematica problem... yet. Why not research and look at papers for an algorithm, and then come back to ask how that algorithm can be implemented? Aug 9 '17 at 3:11
• @J.M. I post my implement in following just.You are a math Big God in mind.Could you give some advice for me?
– yode
Aug 9 '17 at 3:51
• This seems very much like the question you're having. Dec 7 '17 at 11:42

One possibility is to sum all the elements and compare this to the sum of the diagonal elements.

Tr[Abs[mat]]/Total[Abs[mat], 2]


So for a random matrix

mat1 = RandomReal[{-1, 1}, {10, 10}];
Tr[Abs[mat1]]/Total[Abs[mat1], 2]
0.0905167


while for a mostly diagonal matrix:

mat2 = RandomReal[{-1, 1}, {10, 10}] + DiagonalMatrix[RandomReal[{-100, 100}, 10]];
Tr[Abs[mat2]]/Total[Abs[mat2], 2]
0.922929


At least it will always be between zero and one. A problem with the above answer is that it weights all off-diagonal elements the same. The spirit of the OPs request is that elements far from the diagonal should carry more weight. We can implement this via a weight matrix:

par=1.2;
weights = Table[par^Abs[i - j], {i, Length[mat1]}, {j, Length[mat1]}];

Tr[Abs[weights mat1]]/Total[Abs[weights mat1], 2]
0.0497874

Tr[Abs[weights mat2]]/Total[Abs[weights mat2], 2]
0.83005


You can play with the parameter par to choose how much weight should be given to the distant diagonal terms terms.

For a matrix whose elements sum to one, Tr would seem to do what you want.

• That's a good start,but sometimes,the elements is not concentre in the diagonal precisely,but in the near post.such as this matrix,I think it have a good degree of concentration still.
– yode
Aug 9 '17 at 3:08

This is current method,suppose the mat is

mat = {{0, .2, 0, 0},
{0, .1, .2, 0},
{0, .2, 0, 0},
{0, .2, .1, 0}};


I will built a const,which contain all distance form the position of the element to the diagonal.

const = Dispatch[
Normalize[Abs[Subtract @@ #]/Sqrt[2] & /@ #, Total]]] &[
Tuples[Range[Length[mat]], 2]]];


Then I get a rule about the element and its postion

rule = Most[ArrayRules[mat]]


{{1, 2} -> 0.2, {2, 2} -> 0.1, {2, 3} -> 0.2, {3, 2} -> 0.2, {4, 2} ->0.2, {4, 3} -> 0.1}

Measure the degree of concentration

1 - Mean[WeightedData[Values[rule], Keys[rule] /. const]]


0.816667

But I don't sure how to ensure the result always between 0 to 1.A better solution is expected still.

Packed it into a function for using

Concentration[mat_] :=
Module[{const, rule = Most[ArrayRules[mat]]},
const = Dispatch[