2012-04-06 5 views
0

normrnd를 사용하여 정규 분포를 갖는 일반 난수 행렬을 생성하는 함수가 있습니다. 출력은 ROUND1 내지matlab을 사용하여 조건부로 난수 생성

   values(vvvv)= normrnd(0,0.2); 

이다 : ANS =

0.0210 0.1445 0.5171 -0.1334 0.0375 -0.0165  Inf -0.3866 -0.0878 -0.3589 

2 라운드에서 출력되는

: ANS = 3 라운드에서

0.0667 0.0783 0.0903 -0.0261 0.0367 -0.0952 0.1724 -0.2723  Inf  Inf 

출력은 : ANS =

0.4047 -0.4517 0.4459 0.0675 0.2000 -0.3328 -0.1180 -0.0556 0.0845  Inf 

기능이 20 번 반복됩니다.

함수가 완전히 랜덤하다는 것은 명백합니다. 제가 찾는 것은 조건을 추가하는 것입니다.

내가 필요한 것은 다음과 같습니다. 항목에 0.2와 0.3 사이의 값이있는 경우. 그 값은 다음 라운드에서 고정 될 것입니다. 나머지 항목 만 함수 rand를 사용하여 변경됩니다.

나는 rand, randi 및 randn이 예측 가능한 일련의 수를 생성 할 수 있도록 비 음수 정수 sd를 사용하여 난수 생성기를 시드하는 rng (sd)를 발견했습니다.

How to set custom seed for pseudo-random number generator

하지만 행렬의 여러 항목에만 영향을 만드는 방법!

또 다른 문제는 : RNG는 & 통계

답변

2

당신은이 작업을 수행 할 수 있습니다에게 확률의 합병증에 입력 더 직접적으로보다는 실제로 모든 매트릭스를 생성하지 않고 비슷한 얻을 수있는 방법을 MATLAB R2009 사용할 수 없습니다 것 같다, 그것은이다 최종 산출물의 분포에 대해 생각함으로써 그렇게 쉽게 수행 할 수 있습니다.

.2와 .3 사이에있는 N (0, .2)에 의해 분포 된 확률 변수는 확률 p = 0.092입니다.

이 n (20) 번 수행하는 행렬 X의 최종 산출물의 확률 변수를 호출하십시오. (a) X가 .2와 .3 사이에 있고, 당신이 일찍 멈 췄거나, (b) 첫 n-1 추첨에서 .2와 .3 사이의 숫자를 그리지 않았고, n 번째 무승부에.

(b) 발생 확률은 b = (1-p)^(n-1) : 확률 1-p를 갖는 [2, 3] 외부의 독립 이벤트 -1 번. 따라서 (a)의 확률은 1-b이다.

(b)가 발생하면 normrnd에서 숫자를 그립니다. (a)가 발생하면, .2와 .3 사이에있는 조건부 변수를 필요로합니다. 이를 수행하는 한 가지 방법은 .2와 .3에 대한 cdf 값을 찾아 그 사이의 범위에서 균등하게 그립니다. 그런 다음 inverse cdf를 사용하여 원래의 번호로 되돌립니다.이 수행

코드 :

mu = 0; 
sigma = .2; 
upper = .3; 
lower = .2; 
n = 20; 
sz = 15; 

cdf_upper = normcdf(upper, mu, sigma); 
cdf_lower = normcdf(lower, mu, sigma); 
p = cdf_upper - cdf_lower; 
b = (1-p)^(n - 1); 

results = zeros(sz, sz); 
mask = rand(sz, sz) > b; % mask value 1 means case (a), 0 means case (b) 
num_a = sum(mask(:)); 

cdf_vals = rand(num_a, 1) * p + cdf_lower; 
results(mask) = norminv(cdf_vals, mu, sigma); 

results(~mask) = normrnd(mu, sigma, sz^2 - num_a, 1); 

직접 낭비 많은 노력을 포함하는 것입니다 몇 가지 이유 (이 시뮬레이션 할,하지만 분명히 당신의 "마음에 들지 않으면 통계의 합병증 "- 그런데 이것은 통계가 아니라 확률 임), 첫 번째 행렬을 생성 한 다음 원하는 범위에 속하지 않는 요소 만 바꿀 수 있습니다. 예를 들어 :

mu = 0; 
sigma = .2; 
n = 10; 
m = 10; 
num_runs = 20; 
lower = .2; 
upper = .3; 

result = normrnd(mu, sigma, n, m); 
for i = 1 : (num_runs - 1) 
    to_replace = (result < lower) | (result > upper); 
    result(to_replace) = normrnd(mu, sigma, sum(to_replace(:)), 1); 
end 

이 여기 × 1이 일을 경험적 CDFS의 플롯은 10 번 행렬의 동일하다는 것을 입증합니다. (즉, I는 두 가지 기능을 100,000 회를 실행하고 그 결과를 저장 한 다음, y 축에 해당 미만 얻어진 값 부 VS X 축의 값을 플롯 cdfplot을 사용했다.)

그들은 동일합니다. (사실, K-S test은 배포판의 신원을 나타내며 p 값은 .71입니다.)하지만 직접적인 방법은 실행 속도가 더 빠릅니다.

+0

코드는 @Dougal 다음과 같은 오류와 함께 종료 : ??? 직사각형 빈 행렬을 사용한 부적절한 할당. – pac

+0

@pac 방금 좀 더 직접적인 접근 방식을 사용 했으므로 제대로 작동합니다 (몇 가지 작은 실수가 수정되었지만). 그 일이 훨씬 더 빠르고 더 잘 될 것입니다. 그래서 저는 제 대답에서 다른 길을 제거했습니다. 이 매개 변수에 대한 확률 'b'는 .16이므로 행렬의 84 %가 "일찍 중지"됩니다. – Dougal

+0

@pac 직접 실행하는 코드의 작업 버전을 다시 추가했습니다. 나는 실제로 30 초의 생각을 그것에 넣는 것이 더 나은 접근이라고 생각하지만, 무엇이든간에. 또한 'rng'이이 문제와 어떻게 관련되는지 보지 못합니다. 결과를 재현 가능하게 만들려고합니까 아니면 어떻게 든 사용하여 세대를 생성하기를 원하십니까? – Dougal