Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can do this more directly than actually generating all these matrices, and it's pretty easy to do so, by thinking about the distribution of the final output.</p> <p>The probability of a random variable distributed by N(0, .2) lying between .2 and .3 is p ~= .092.</p> <p>Call the random variable of the final output of your matrix X, where you do this n (20) times. Then either (a) X lies between .2 and .3 and you stopped early, or (b) you didn't draw a number between .2 and .3 in the first n-1 draws and so you went with whatever you got on the nth draw.</p> <p>The probability of (b) happening is just b=(1-p)^(n-1): the independent events of drawing outside [.2, .3], which have probability 1-p, happend n-1 times. Therefore the probability of (a) is 1-b.</p> <p>If (b) happened, you just draw a number from <code>normrnd</code>. If (a) happened, you need the value of a normal variable, conditional on its being between .2 and .3. One way to do this is to find the cdf values for .2 and .3, draw uniformly from the range between there, and then use the inverse cdf to get back the original number.</p> <p>Code that does this:</p> <pre><code>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) &gt; 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); </code></pre> <hr/> <p>If you want to simulate this directly for some reason (which is going to involve a lot of wasted effort, but apparently you don't like "the complications of statistics" -- by the way, this is probability, not statistics), you can generate the first matrix and then replace only the elements that don't fall in your desired range. For example:</p> <pre><code>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 &lt; lower) | (result &gt; upper); result(to_replace) = normrnd(mu, sigma, sum(to_replace(:)), 1); end </code></pre> <hr /> <p>To demonstrate that these are the same, here's a plots of the empirical CDFs of doing this for 1x1 matrices 100,000 times. (That is, I ran both functions 100k times and saved the results, then used <code>cdfplot</code> to plot values on the x axis vs portion of the obtained values that are less than that on the y axis.)</p> <p><img src="https://i.imgur.com/ZUR4I.png" /></p> <p>They're identical. (Indeed, a <a href="http://en.wikipedia.org/wiki/K-S_Test" rel="nofollow noreferrer">K-S test</a> for identity of distribution gives a p-value of .71.) But the direct way was a bunch faster to run.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload