Suppose, I wanted to show (empirically) that randperm(n,k) from matlab indeed produces uniformly distributed random samples of size k from a set N of n elements. How can I plot the number of occurences divided by the total number of k-subsets drawn from N, after drawing repeatedly?
You can simply use the indices drawn from randperm to increment a counter vector.
n=1e5;
k=1e4;
maxiter = 1e5;
% This array will be used to count the number of times each integer has been drawn
count=zeros(n,1);
for ii=1:maxiter
p=randperm(n,k);
% p is a vector of k distinct integers in the 1:n range
% the array count will be incremented at indices given by p
count(p)=count(p)+1;
end
% A total of k*maxiter integers has been drawn and they should be evenly
% distributed over n values
% The following vector should have values close to 1 for large values of maxiter
prob = count*n/(k*maxiter);
Related
I am using Matlab function round(rand(256)) to create a square matrix of size 256x256 with random distribution of 0s and 1s.
What I specifically want to do is that I want to somehow specify number of 1s that rand() (or any other relevant function for that matter) to generate and distribute throughout the matrix randomly
Magdrop’s answer is the most straight-forward method, it computes the percentile of the random values to determine the threshold.
Another two options involve randperm:
Randomly permute all indices into the matrix, then threshold:
sz = [256,256]; % matrix size
n = 256; % number of zeros
M = randperm(prod(sz)) <= n;
M = reshape(M,sz);
Randomly permute indices and select n as the locations of the ones:
indx = randperm(prod(sz),n);
M = zeros(sz);
M(indx) = 1;
You could also generate the random value the usual way, but before you round them, sort them as a vector. The number of 1s will the index in the sorted vector you want to cut for 1s or 0s. For example, let say we want 50 1s:
matrix = rand(256,256);
vec = sort(reshape(matrix,[],1));
thresh = vec(50);
matrix(matrix <= thresh) = 1;
matrix(matrix > thresh) = 0;
You could use the randi function to determine the locations of where to insert the ones, and then place those ones into your matrix. For example for n ones:
matrix = zeros(256,256);
onesIndices = randi([0 256*256],1,n);
matrix(onesIndices) = 1;
One problem with this approach is that randi can generate repeat values, though for this example, where the size of the matrix is large and the number of ones is low, this is pretty unlikely. You could test if this is the case and "reroll:" so if sum(sum(matrix)) is less than n you know you had a repeat value.
Edit: a better approach is to use randperm instead of randi and only take the first n elements. This should prevent there from being repeats and having to re-roll.
Thank you for any help in advance. I have a large matrix: 1,000,000 rows and 10 columns. I would like to sum each row and create a new matrix with only the rows that sum to integers. I've tried this so far and manipulated it in many ways, but I'm stuck. How can I do this?
for k = 1:1000000
x = sum(A(k,:)) %A is my large matrix
if x-round(x,0)==0
y = [y;x]% y is my new matrix
end
end
Rather than using a for loop and continuously expanding y which is going to be extremely slow for large x arrays, you can use the second input of sum to compute the sum for each row, and then you can determine which rows sum to an integer by comparing the rounded and original versions using a very small epsilon (the proper way to compare floating-point numbers).
% Sum each row and divide by 3
row_sums = sum(x, 2) / 3;
% Determine which of the row-wise sums are integers
sum_is_integer = abs(round(row_sums) - row_sums) < eps;
% If you want the sums that were integers
y = row_sums(sum_is_integer);
% If you want a sub-matrix containing only the rows where the sums were an integer
z = x(sum_is_integer, :);
I wanted to know how I can go about randomly placing numbers (up to 10 numbers) in a matrix. The numbers will range from 1 to 10.
I am starting with A = zeros(5,8), then randomly place the 10 random numbers around the matrix.
Example of matrix:
N=20; %// number of columns
M=1024; %// number of rows
NumRand = 20; %// number of random numbers
RandomScalars = rand(NumRand,1); %// random numbers
MyMatrix= sparse(M,N); %// initialise matrix
Idx = randperm(M*N,NumRand); %// get indices to be filled
MyMatrix(Idx) = RandomScalars; %// fill indexed places
Basically you use randperm to create a certain number of linear indices to index your matrix. Simply place the desired numbers there and you're done.
I'm facing a problem. I have a zeros matrix 600x600. I need to fill this matrix with 1080 1s randomly. Any suggestions?
Or, use the intrinsic routine randperm thusly:
A = zeros(600);
A(randperm(600^2,1080)) = 1;
A = sparse(600,600); %// set up your matrix
N=1080; %// number of desired ones
randindex = randi(600^2,N,1); %// get random locations for the ones
while numel(unique(randindex)) ~= numel(randindex)
randindex = randi(600^2,N,1); %// get new random locations for the ones
end
A(randindex) = 1; %// set the random locations to 1
This utilises randi to generate 1080 numbers randomly between 1 and 600^2, i.e. all possible locations in your vectors. The while loop is there in case it happens that one of the locations occurs twice, thus ending up with less than 1080 1.
The reason you can use a single index in this case for a matrix is because of linear indexing.
The big performance difference with respect to the other answers is that this initialises a sparse matrix, since 1080/600^2 = 0.3% is very sparse and will thus be faster. (Thanks to #Dev-iL)
This is one way to do it,
N = 1080; % Number of ones
M = zeros(600); % Create your matrix
a = rand(600^2,1); % generate a vector of randoms with the same length as the matrix
[~,asort] = sort(a); % Sorting will do uniform scrambling since uniform distribution is used
M(asort(1:N)) = 1; % Replace first N numbers with ones.
I am having a problem at the final calculation of my code, the very last part, where log is the natural log, I need RD=facs.*log(log(facs)) to divide sigmafac, or robin=sigmafac./RD. My RD goes from 1 to 100, so does my sigmafac. why is there a matrix dimension mismatch?
I want the corresponding number (numbas) of RD to divide the correspoding number of sigmafac, the all have the same dimension, so I do not see where the problem is coming from. I realize that RD(1)=-inf, is that is what causing the problem? and how do I fix it?
code:
n=100;
primlist=2; % starting the prime number list
for numba=1:n;
if mod(2+numba,primlist)~=0
primlist=[primlist;2+numba]; %generating the prime number list
end
end
fac=1; %initializing the factorials
RD=0;
for numbas=2:n
%preallocating vectors for later use
prims=zeros(size(primlist));
pprims=zeros(size(primlist));
pow=prims;
for i=1:length(primlist) % identifying each primes in the primlist
for k=1:10
if mod(numbas,primlist(i).^k)==0
prims(i)=primlist(i); % sum of all the powers of prims, such that prims divide numbas
pow(i)=k; % collecting the exponents of primes
end
end
if primlist(i)<=numbas
pprims(i)=primlist(i); % primes less than or equal to numbas
end
end
% converting column vectors to row vector
PPRIMS=pprims';
PRIMS=prims';
POW=pow';
%Creating the vectors
PLN(numbas,:)=PPRIMS; % vector of primes less than or equal to number
PPV(numbas,:)=PRIMS; % prime divisor vector
PVE(numbas,:)=POW; % highest power of each primes for every number
RVE=cumsum(PVE); % the cummulative sum of the exponents
RVE(RVE~=0)=RVE(RVE~=0)+1; %selects each non zero element then add 1
%factorial
fac=fac*numbas;
facs(numbas)=fac; %storing the factorials
if facs==1
RD==1; % log(log(facs1))) does not exist
else RD=facs.*log(log(facs));
end
end
% setting up sum of divisor vector
NV=PLN.^RVE-1; % numerator part of sum of divisors vector
DV=PLN-1; % denominator part of sum of divisors
NV(NV==0)=1; % getting rid of 0 for elementwise product
DV(DV==-1)=1; % getting rid of -1 for elementwise product
sigmafac=prod(NV,2)./prod(DV,2); %sum of divisors
robin=(sigmafac)./(RD)
Whenever you get such an error, your first check should be to test
size(sigmafac)
size(RD)
In this case, you'll get
ans =
100 1
ans =
1 100
So they are NOT the same size. You need to take the transpose of one or the other and then your division will work fine.
Your sigmafac is 100x1 but your RD is 1x100 which is producing the error. If you want this to work just change
robin=(sigmafac)./(RD)
to
robin=(sigmafac)'./(RD)
This will make sigmafac a 1x100 (transpose) and then your vectors will have the same dimension and you will be able to do the division.