[R] Re : Generate a random bistochastic matrix
Martin Maechler
maechler at stat.math.ethz.ch
Mon Oct 16 16:29:47 CEST 2006
A simpler approach --- as in similar problems ---
is to use an iterative solution which works quite fast for any 'n'.
Interestingly, the number of necessary iterations seems to
*decrease* for increasing 'n' :
bistochMat <- function(n, tol = 1e-7, maxit = 1000)
{
## Purpose: Random bistochastic *square* matrix (M_{ij}):
## M_{ij} >= 0; sum_i M_{ij} = sum_j M_{ij} = 1 (for all i, j)
## ----------------------------------------------------------------------
## Arguments: n: (n * n) matrix dimension;
## ----------------------------------------------------------------------
## Author: Martin Maechler, Date: 16 Oct 2006, 14:47
stopifnot(maxit >= 1, tol >= 0)
M <- matrix(runif(n*n), n,n)
for(i in 1:maxit) {
M <- M / outer((rM <- rowSums(M)), (cM <- colSums(M))) * sum(rM) / n
if(all(abs(c(rM,cM) - 1) < tol))
break
}
## cat("needed", i, "iterations\n")
## or rather
attr(M, "iter") <- i
M
}
attr(M <- bistochMat(70), "iter")
## typically:
## [1] 8
attr(M <- bistochMat(10), "iter")
## -> 13, 16, 15, 17, ...
set.seed(101) ; attr(M <- bistochMat(10), "iter") ## 15
set.seed(101) ; attr(M <- bistochMat(10, tol = 1e-15), "iter")## 32
------------------------
Initially, I tried to solve the general [ n x m ] case.
It seems that needs a slightly smarter "bias correction"
instead of just 'sum(M) / n'.
If someone figures that out, please post your solution!
Regards,
Martin Maechler, ETH Zurich
More information about the R-help
mailing list