how to make a function that generate uniformely distributed random matrix
Show older comments
Hi every one..
I am going to make a function which takes three input arguments limit,a,b in that order. The function returns an a-by-b matrix of uniformly distributed random integers between 1 and limit inclusive. I am not allowed to use randi, but i can use rand. To make sure that my result is indeed uniformly distributed, test the output of the function by using the built-in function hist, which plots a histogram.
to make such function i am using that codes
function rad=rad1(limit,n,m)
mat=zeros(n,m);
for i=1:n
for j=1:m
a=rand(1,limit);
mat(i,j)=floor(a)
end
end
end
but i getting error every time.Can anybody assist me to make such function...Thanks in advance
Accepted Answer
More Answers (3)
The syntax of rand is completely different from that of randi. The arguments you pass to rand are just the size of the matrix you want, never the bounds, rand always return floating point numbers between 0 and 1.
Thus to create a matrix of size m x n, of numbers (floating point) between x and y, you'd do:
r = rand(m, n) * (y-x) + x;
You can figure out the rest of your function yourself.
5 Comments
Muhammad Usman Saleem
on 7 May 2015
Guillaume
on 7 May 2015
You're using rand wrong. It does not work like randi. rand doesn't take a limit. I've linked to the documentation for you in my answer. Look at it.
I've also given you the code to generate a matrix between two numbers using rand. (i.e. multiply the rand output| by the difference between the limits and add the lower limit).
I'm not sure what is hard to understand in any of this.
Guillaume
on 7 May 2015
Muhammad comments copied here:
Thanks Guilaume... I am now use that function
function rad=rad1(limit,n,m)
mat=zeros(n,m);
for i=1:n
for j=1:m
a=limit*rand(1,1);
mat(i,j)=floor(a)
end
end
rad=mat(i,j)
end
Other comment:
other problem is that these no are not uniformly distributed random integers...
Please comment in the right answer (and use the {} Code button to format code)
As stated several times:
a = limit * rand; %no need for (1, 1)
WILL NOT generate numbers between [1, limit], but between [0, limit]. I've given the correct formula in my original answer. Just replace y by limit and x by 1.
Secondly, if you want uniformly distributed integer, using floor like you did is wrong, since it will round numbers between [0, 1[ to 0, [1, 2[ to 1, etc. up to [limit-1, limit[ rounded to limit-1, but just [limit] to limit. Hence the probability of limit appearing is much lower.
Hopefully from this, you can see were you went wrong. You need to generate the correct range of floating point numbers before rounding.
Brendan Hamm
on 7 May 2015
Hence P(a = limit) = 0.
Purushottama Rao
on 7 May 2015
1 vote
Replace a=rand(1,limit); with a=limit*rand(1,1); in your code
13 Comments
Guillaume
on 7 May 2015
This will not generate a number between [1, limit].
Purushottama Rao
on 7 May 2015
Yeah..this is a sort of generating numbers between [0 9] along with floor function. can we look at something like floor(a)+1
Muhammad Usman Saleem
on 7 May 2015
Purushottama Rao
on 7 May 2015
put semicolon at
mat(i,j)=floor(a)
Muhammad Usman Saleem
on 7 May 2015
Purushottama Rao
on 7 May 2015
Edited: Purushottama Rao
on 7 May 2015
The problrm is associated with floor function. If we consider real values, it still follows a uniform distribution.
do you need to deal only with integer values?
Michael Haderlein
on 7 May 2015
To get a readable copy of your function, I copied and formatted it here:
function rad=rad1(limit,n,m)
mat=zeros(n,m);
for i=1:n
for j=1:m
a=limit*rand(1,1);
mat(i,j)=floor(a);
end
end
rad=mat(i,j);
end
- There's zero need for any loop here. As this seems to be homework, I don't want to give the correct solution but only tell you to think about vectorization.
- rand will give something 0<x<1. If you multiply this with 10, for instance, you will get something between 0 and 9. So you'll need to add 1 as Purushottama has mentioned before.
- You return mat(i,j) only. This is only the very last element (lower right corner of the matrix). I guess you want to return entire mat.
Guillaume
on 7 May 2015
@Michael,
It's unfortunately not clear from the official documentation, but I think rand generates numbers in the range [0, 1], not ]0, 1[. For this assignment, it probably does not matter.
Michael Haderlein
on 7 May 2015
I agree that it probably does not matter and is rather an academic question (the probability of getting the smallest/largest value of whatever the interval is will be extremely low).
The documentation of R2014a says "rand returns a pseudorandom scalar drawn from the standard uniform distribution on the open interval (0,1)." which clearly cuts 0 and 1 (and made me give the statement in the comment above).
Now, to my surprise I just found the online documentation to only say "rand returns a single uniformly distributed random number between 0 and 1." The fact that somebody at TMW obviously took the effort to change that sentence is a suggests that someone figured out that the older version was wrong and the interval indeed is closed [0,1].
Guillaume
on 7 May 2015
Yes, I looked at the 2015 doc and saw that it was not specified, and assumed it was closed from the example on how to generate numbers in a range. That example shows a closed interval.
From this discussion, it looks like rand does use an open interval. I'm not sure why mathworks took the effort to make the documentation less precise.
Brendan Hamm
on 7 May 2015
The 2015 doc simply says "generates values between 0 and 1". This is to allow for the possibility of changing the algorithm used to generate random numbers, as each algorithm will have a different period and therefore produce a different interval of values. Unless you change the algorithm you are as close to [0,1] as possible.
While the doc may not mention this, it is clear from Cleve Moler's blog on the Mersenne Twister algorithm. The values generate are actually in the range [2^(-53), 1-2^(-53)]. It is impossible to generate values 1 with this algorithm, but you could generate values of 0, but they will be rejected by the algorithm. This is really irrelevant as this is the machine precision of a double.
eps/2 == 2^(-53)
ans =
1
Muhammad Usman Saleem
on 7 May 2015
Purushottama Rao
on 8 May 2015
@MUS: You can try to use disp function after the last ietration for varaible 'matt'
Muhammad Usman Saleem
on 7 May 2015
0 votes
2 Comments
Michael Haderlein
on 8 May 2015
No matter where the variable mat is coming from,
rad=mat(i,j);
will return exactly 1 value (as long as i and j are scalar values). If you want the full array, don't use the indices here
rad=mat;
If you want a short, vectorized and correct version, see Thorsten's answer. As this still seems to be homework and the learning effect of simply using a given answer is rather low, my advise would be to go through this fully equivalent function step by step:
function r = myrandi(limit, a, b)
rand_doubles_0_1=rand(a,b);
rand_doubles_0_limit=limit*rand_doubles_0_1;
r=ceil(rand_doubles_0_limit);
Use a limit of 10 and set a,b to maybe 3 or 4 to keep it simple.
Muhammad Usman Saleem
on 8 May 2015
Categories
Find more on Multivariate Normal Distribution in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!