how to make a function that generate uniformely distributed random matrix
显示 更早的评论
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
采纳的回答
更多回答(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 个评论
Muhammad Usman Saleem
2015-5-7
Guillaume
2015-5-7
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
2015-5-7
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
2015-5-7
Hence P(a = limit) = 0.
Purushottama Rao
2015-5-7
1 个投票
Replace a=rand(1,limit); with a=limit*rand(1,1); in your code
13 个评论
Guillaume
2015-5-7
This will not generate a number between [1, limit].
Purushottama Rao
2015-5-7
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
2015-5-7
Purushottama Rao
2015-5-7
put semicolon at
mat(i,j)=floor(a)
Muhammad Usman Saleem
2015-5-7
Purushottama Rao
2015-5-7
编辑:Purushottama Rao
2015-5-7
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
2015-5-7
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
2015-5-7
@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
2015-5-7
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
2015-5-7
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
2015-5-7
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
2015-5-7
Purushottama Rao
2015-5-8
@MUS: You can try to use disp function after the last ietration for varaible 'matt'
Muhammad Usman Saleem
2015-5-7
0 个投票
2 个评论
Michael Haderlein
2015-5-8
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
2015-5-8
类别
在 帮助中心 和 File Exchange 中查找有关 Multivariate Normal Distribution 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!