6

I am trying to create a transition matrix for a network. In order to do this, I need to sum down the column (the out degree), and then divide the column by the out degree in order to normalize it.

I am able to sum down the column. What I am unable to figure out how to do efficiently and easily is to divide the column by the sum.

L = {{0, 1, 0, 1, 0, 0, 0}, 
     {0, 0, 1, 1, 1, 0, 0}, 
     {0, 1, 0, 1, 0, 0, 0}, 
     {0, 0, 0, 0, 1, 0, 0}, 
     {1, 0, 0, 0, 0, 0, 0}, 
     {0, 0, 0, 0, 0, 0, 1}, 
     {0, 0, 0, 0, 0, 1, 0}};
rm -rf
  • 88,781
  • 21
  • 293
  • 472
olliepower
  • 2,254
  • 2
  • 21
  • 34

3 Answers3

12

You can use Normalize with its second argument for this purpose:

(mat = Normalize[#, Total] & /@ Transpose@L // Transpose) // MatrixForm

Instead, if you were normalizing the rows by the sum of their elements, you could simply leave out the transposes and do

mat = Normalize[#, Total] & /@ L

or even

mat = #/Tr@#& /@ L

For your specific problem (transition matrix), you can use the new Markov process related functions in version 9 to get the transition matrix:

With[{m = DiscreteMarkovProcess[, L]},
   mat = MarkovProcessProperties[m, "TransitionMatrix"]
] // MatrixForm
rm -rf
  • 88,781
  • 21
  • 293
  • 472
10

If you need to do this with all columns, then:

Transpose[#/Total[#] & /@ Transpose[L]]
Vitaliy Kaurov
  • 73,078
  • 9
  • 204
  • 355
4

Why transpose when you don't have to?

#/Total[L] & /@ L

(Just resurrecting this for a bit of "code golf.")

Kellen Myers
  • 2,701
  • 15
  • 18
  • 3
    The answer to my silly rhetorical question is: because it is faster. My "shorter" code results in longer computational time. The solution using Transpose will divide each row (which was, originally, a column) by a single value, List / Real. My answer divides each row by the list of column totals, List / List. At any large scale, this adds up to cost way more than 2x Transpose. There's a long comment for a short answer. – Kellen Myers Jun 19 '17 at 06:33