6

A Markov Matrix is a square matrix,which have two features:

  • All elements great than or equal to $0$(But I hope all element great than or equal to $0.1$)
  • All the columns add up to $1$

I have a custom function for this

MarkovMatrix[dim_] := 
 Module[{m}, Label[start]; 
  m = Transpose[
    Append[#, 1 - Total[#]] & /@ 
     RandomReal[1, {dim, dim - 1}, WorkingPrecision -> 2]]; 
  If[AllTrue[m, # > .1 &, 2], m, Goto[start]]; m]

Usage:

For example to generate a 4*4 matrix

MatrixForm[m = MarkovMatrix[4]]

But my MarkovMatrix is low efficiency function.Are there any better method can do this?

rhermans
  • 36,518
  • 4
  • 57
  • 149
yode
  • 26,686
  • 4
  • 62
  • 167
  • Surely you mean the columns add up to $1$ – Feyre Jun 27 '16 at 18:18
  • 2
    Transpose[Normalize[#, Total] & /@ RandomReal[1, {4, 4}]]? Anyway: the more common term is stochastic matrix. – J. M.'s missing motivation Jun 27 '16 at 18:18
  • @Feyre OMG.I make a typo.Thanks for your reminder. – yode Jun 27 '16 at 18:22
  • @J.M. I have to say this is a beautiful solution.It deserve a answer but a comment.Another extra my request can you make all element great than or equal to $0.1$ with same elegant method? (Thanks for your term. :) – yode Jun 27 '16 at 18:29
  • 2
    relevant: http://mathematica.stackexchange.com/questions/69707/random-real-numbers-that-sum-up-to-specific-value and http://mathematica.stackexchange.com/q/33652/2079. And for heavens sake never use Goto. – george2079 Jun 27 '16 at 19:59

3 Answers3

10

Here's something even more compact than my proposal in the comments:

Standardize[RandomReal[1, {4, 4}], 0 &, Total]

If you must have a left stochastic matrix where all the entries should be greater than a set value, you can do rejection sampling: keep generating a matrix as long as the smallest value is smaller than the cutoff:

While[Min[sm = Standardize[RandomReal[1, {4, 4}], 0 &, Total]] < 0.1]; sm

If a doubly stochastic matrix is desired (that is, all columns and all rows sum to unity), some more trickery is necessary:

While[Min[dsm = FixedPoint[Standardize[Transpose[Standardize[#, 0 &, Total]],
                                       0 &, Total] &, RandomReal[1, {4, 4}],
                           SameTest -> (Norm[#1 - Transpose[#2], "Frobenius"] <
                                        1.*^-12 &)]] < 0.1]; dsm

I make no guarantees on the distribution followed by the matrices generated by either method.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
8

Assuming you want uniformly distributed n-dimensional probability vectors with a minimum value, I think you can use:

MarkovMatrix[n_, min_:0] := If[min n<1,
    Transpose @ RandomPoint[Simplex[IdentityMatrix[n](1-min n)], n] + min,
    $Failed
]

For example:

MarkovMatrix[4, .1] // TeXForm

$\left( \begin{array}{cccc} 0.378616 & 0.267013 & 0.416824 & 0.142604 \\ 0.14229 & 0.305494 & 0.177654 & 0.203273 \\ 0.231628 & 0.175853 & 0.154734 & 0.178135 \\ 0.247466 & 0.251641 & 0.250788 & 0.475988 \\ \end{array} \right)$

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
  • For earlier versions that do not have RandomPoint[], here is some equivalent code: MarkovMatrix[n_, min_: 0] := If[min n < 1, Transpose[((1 - min n) Append[#, 1 - Total[#]]) & /@ RandomVariate[DirichletDistribution[ConstantArray[1, n]], n]] + min, $Failed] – J. M.'s missing motivation Jul 26 '17 at 14:09
  • Just discovered the //TeXForm command. I cried, for real. – R.W May 06 '20 at 00:36
4

Here is my idea

make[n_] := ConstantArray[0.1, {n, n}] + (
                 (1 - 0.1 n) #/Total[#, {2}] &[RandomReal[{0, 1}, {n, n}]])

Because of the minimum you specified for each entry, this works for $n<11$ only. Did you consider letting the minimum value dependent on $n$ in a decreasing manner?

Coolwater
  • 20,257
  • 3
  • 35
  • 64
  • Thanks for your solution.And I have no that thinking,I just don't hope the element too tiny,which will make some troubles for my processing in following. – yode Jun 27 '16 at 18:34