Возможно, этот ответ поможет реализовать его на практике:
Одним классом матриц, обладающим этим свойством неотрицательной определенности, является Wishart Distribution . А сэмплы из ~ W () такие, что все недиагональные записи находятся между границами [l, u], будут соответствовать вашему вопросу. Однако я не считаю, что это то же самое, что распределение всех положительно определенных матриц с недиагоналями в [l, u].
На странице википедии есть алгоритм для вычисления из ~ W ().
Более простое, хакерское решение (возможно, приближающееся к этому):
(учитывая, что u> l и l> 0)
- взять из многовариантной нормали, где сигма = среднее (l, u).
- Затем берём выборку, вычисляем её матрицу корреляции => C
- Эта матрица будет иметь некоторую случайность (нечеткость), но математика того, сколько она будет иметь, немного не в моей области. Значения недиагностиков в этой C-матрице ограничены [-1,1] со средним значением (l, u). По глазному яблоку я предполагаю какую-то бета / экспоненциальную. В любом случае, это непрерывное распределение отключенных диаграмм в C гарантирует, что оно не будет вести себя и лежать внутри границ (l, u), если (l, u) = [-1,1].
- Вы можете отрегулировать количество «пуха», увеличив / уменьшив длину выборки на шаге 1. Я бы поспорил (бездоказательно), что величина дисперсии в нечетных диагонали C пропорциональна квадратному корню из количество образцов.
Так что, кажется, нетривиально, чтобы действительно ответить!
Как и предлагали другие постеры, вы можете сгенерировать из Wishart, а затем оставить те, где свойство, которое вы хотите, соответствует действительности, но вы можете пробовать в течение длительного времени! Если вы исключите тех, кто является 0-определенным (это слово?), То это должно хорошо работать для генерации хороших матриц. Однако это не является истинным распределением всех матриц pos-def, чьи недиагностики находятся в [l, u].
Код (в R) для предложенной выше схемы немой выборки
sigma1 <- function(n,sigma) {
out <- matrix(sigma,n,n)
diag(out) <- 1
return (out)
}
library(mvtnorm)
sample_around_sigma <- function(size, upper,lower, tight=500) {
# size: size of matrix
# upper, lower: bounds on the corr, should be > 0
# tight: number of samples to use. ideally this
# would be calcuated such that the odd-diags will
# be "pretty likely" to fall in [lower,upper]
sigma <- sigma1(size,mean(c(upper,lower)))
means <- 0*1:size
samples <- rmvnorm(n=tight, mean=means,sigma=sigma)
return (cor(samples))
}
> A <- sample_around_sigma(5, .3,.5)
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 1.0000000 0.3806354 0.3878336 0.3926565 0.4080125
[2,] 0.3806354 1.0000000 0.4028188 0.4366342 0.3801593
[3,] 0.3878336 0.4028188 1.0000000 0.4085453 0.3814716
[4,] 0.3926565 0.4366342 0.4085453 1.0000000 0.3677547
[5,] 0.4080125 0.3801593 0.3814716 0.3677547 1.0000000
>
> summary(A[lower.tri(A)]); var(A[lower.tri(A)])
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.3678 0.3808 0.3902 0.3947 0.4067 0.4366
[1] 0.0003949876