3
$\begingroup$

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]]

Mathematica graphics

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

Mathematica graphics

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?

$\endgroup$
  • 2
    $\begingroup$ …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 ? $\endgroup$ – xzczd Aug 9 '17 at 2:27
  • $\begingroup$ @xzczd Wow,indeed,but it is produce in MMA.if other think as you think I will transform it to that site.Thanks. :) $\endgroup$ – yode Aug 9 '17 at 2:30
  • 2
    $\begingroup$ 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? $\endgroup$ – J. M. will be back soon Aug 9 '17 at 3:11
  • $\begingroup$ @J.M. I post my implement in following just.You are a math Big God in mind.Could you give some advice for me? $\endgroup$ – yode Aug 9 '17 at 3:51
  • $\begingroup$ This seems very much like the question you're having. $\endgroup$ – Thies Heidecke Dec 7 '17 at 11:42
2
$\begingroup$

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.

$\endgroup$
0
$\begingroup$

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

$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – yode Aug 9 '17 at 3:08
0
$\begingroup$

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[
   Thread[Rule[#, 
       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[
    Thread[Rule[#, 
        Normalize[Abs[Subtract @@ #]/Sqrt[2] & /@ #, Total]]] &[
     Tuples[Range[Length[mat]], 2]]]; 
  1 - Mean[WeightedData[Values[rule], Keys[rule] /. const]]]
$\endgroup$
  • 1
    $\begingroup$ Did you come up with this yourself, or did you get this from some reference? $\endgroup$ – J. M. will be back soon Aug 9 '17 at 3:56
  • $\begingroup$ @J.M. Actually from my mind..If I have referenced,I will add that link always. $\endgroup$ – yode Aug 9 '17 at 3:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.