generation of random number in MATLAB - matlab

I would like to generate three sets of random variables and I dont want them to be the same
for example if I want to generate the following sets ranged from 1 to 10
Set1= [ 1 4 ]
set2= [ 3 5 ]
Set3= [ 7 9]

You can create an array of unique random numbers using the function "randperm" and then divide the array into sets.
x = randperm(10,6);
Set1 = x(1:2);
Set2 = x(3:4);
Set3 = x(5:6);

After choosing two elements for each set, it's essential to randomize the remaining elements to choose from for the next iteration . The code below is trying to achieve it -
set123 = zeros(3,2); %// Pre-allocate for the output
array1 = 1:10; %// Array of numbers to choose from for the first iteration
for k = 1:3
%// Create many possible combinations of such two numbers from the sets.
%// The sets would have 10 elements to choose from at the start and
%// then 8 and then 6.
combs = nchoosek(array1,2);
%// At each stage all the possible combinations of the pairs must be
%// juggled and one of them must be selected randomly and then indexed
%// to get the set for this iteration
choosen_rowind = randperm(size(combs,1),1);
set123(k,:) = combs(choosen_rowind,:);
%// Setup the array of numbers left to choose from the next iteration
array1 = setdiff(array1,set123);
end
%// set123 is the desired output in a single array

If I understand correctly, you want to take r-times-c random variables (in your case r=3, c=2) from the set {m,m+1,...,n} (in your case n=1 and m=10), without repetition. I assume you want a (jointly) uniform distribution.
For that you use randsample:
result = reshape(randsample(m:n, r*c), r, c);

Related

I wrote the following code in matlab to randomize and after that round numbers 3 to 8 in 3x4 matrix but i want to not be repeated numbers in rows

i wrote this code for randomize and round numbers
x=3+5*rand(3,4);
for n=1:3
for m=1:4
y(n,m)=round(x(n,m));
end
end
y
Using the randperm() function may be an option. The first argument of randperm() sets the range. In this case randperm(6,4) will generate 4 numbers that are within the range 1 to 6 (a random permuatation of integers in this case permutations of 6). If we add 2 to this result we can generate an array of length 4 that will have values ranging from 3 to 8. Here we can use one for-loop and generate the rows upon each iteration.
Array = zeros(3,4);
for Row = 1: 3
Array(Row,:) = randperm(6,4) + 2;
end
Array
First of all the rand() function returns numbers between 0 and 1, so it probably doesn't make sense to use this function and then round the numbers off. If you're looking for random integers use randi() instead.
With this in mind, the following code produces a 3 by 4 matrix filled with random integers and no repeats:
maxInteger = 12; %change to any number greater than 3x4 = 12
y = randi(maxInteger, 3, 4);
used = [];
for i = 1:numel(y)
while sum(find(used == y(i)))>0
y(i) = randi(maxInteger);
end
used = [used, y(i)];
end
If the while loop takes too long (as might happen with large matrices) consider filling a matrix by pulling and removing elements from a predecided list of integers.

Create a submatrix using random columns and loop

I have a 102-by-102 matrix. I want to select square sub-matrices of orders from 2 up to 8 using random column numbers. Here is what I have done so far.
matt is the the original matrix of size 102-by-102.
ittr = 30
cols = 3;
for i = 1:ittr
rr = randi([2,102], cols,1);
mattsub = matt([rr(1) rr(2) rr(3)], [rr(1) rr(2) rr(3)]);
end
I have to extract matrices of different orders from 2 to 8. Using the above code I would have to change the mattsub line every time I change cols. I believe it is possible to do with another loop inside but cannot figure out how. How can I do this?
There is no need to extract elements of a vector and concatenate them, just use the vector to index a matrix.
Instead of :
mattsub = matt([rr(1) rr(2) rr(3)], [rr(1) rr(2) rr(3)]);
Use this:
mattsub = matt(rr, rr);
Defining a set of random sizes is pretty easy using the randi function. Once this is done, they can be projected along your iterations number N using arrayfun. Within the iterations, the randperm and sort functions can be used in order to build the random indexers to the original matrix M.
Here is the full code:
% Define the starting parameters...
M = rand(102);
N = 30;
% Retrieve the matrix rows and columns...
M_rows = size(M,1);
M_cols = size(M,2);
% Create a vector of random sizes between 2 and 8...
sizes = randi(7,N,1) + 1;
% Generate the random submatrices and insert them into a vector of cells...
subs = arrayfun(#(x)M(sort(randperm(M_rows,x)),sort(randperm(M_cols,x))),sizes,'UniformOutput',false);
This can work on any type of matrix, even non-squared ones.
You don't need another loop, one is enough. If you use randi to get a random integer as size of your submatrix, and then use those to get random column and row indices you can easily get a random submatrix. Do note that the ouput is a cell, as the submatrices won't all be of the same size.
N=102; % Or substitute with some size function
matt = rand(N); % Initial matrix, use your own
itr = 30; % Number of iterations
mattsub = cell(itr,1); % Cell for non-uniform output
for ii = 1:itr
X = randi(7)+1; % Get random integer between 2 and 7
colr = randi(N-X); % Random column
rowr = randi(N-X); % random row
mattsub{ii} = matt(rowr:(rowr+X-1),colr:(colr+X-1));
end

generate different random variable

I want to generate 5 different random variables, & I want also to satisfy other condition which is N(rand1,rand2) =0 where N is 10-by-10 matrix that contains 0s & 1s.
This is the code that I wrote , it generate different random number , but I want to satisfy the other condition.
nb_sources=5;
nb_Des=5;
rand_nb= randperm(n,n);
source = [rand_nb(1:nb_sources)] ;
distination= [rand_nb(nb_sources+1:nb_sources+nb_Des)] ;
Since you're interested only in N(r1,r2)=0, you need to enumerate all these elements of N (lets say from from 1 to 30), generate 5 random numbers as rand(30,5,1) and pick up the indices. E.g. something like this
Nelem = 5;
[I,J] = find(N==0);
ind = randperm(size(I,1));
Res=[I(ind(1:Nelem)),J(ind(1:Nelem))];

randomly disperse numbers in array

I am trying to randomly disperse different numbers in MATLAB array:
I have two 3's, four 2's and I want to randomly populate ones vector (size 10,1).
End result look something like this:
A = [1;3;1;2;3;2;2;1;1;2;1;1]
Then I want to fix the values in A but add more random elements but I can only replace with higher numbers:
For example, to the matrix above I will randomly add two more 2's and two more 3's giving something like this
A= [3;3;2;2;3;2;2;2;1;2;1;3]
M = [3;3;2;2;2;2];
M(end+1:end+4) = 1;
M=M(randperm(10))
The second half of your question needs a lot of clarification.
First part
You can use randsample for that:
A = ones(1,12); %// original values
v = [3 3 2 2 2 2]; %// values to "disperse" in A
ind_replace = randsample(1:numel(A), numel(v)); %// index of entries to be replaced
A(ind_replace) = v;
If you don't have randsample (which is part of the Statistics Toolbox), use randperm and select the first few elements:
ind_replace = randperm(numel(A));
ind_replace = ind_replace(1:numel(v));
A(ind) = v;
Second part
To only replace entries which equal 1:
v = [2 2 3 3]; %// values to "disperse" among the 1 values in A
ind_ones = find(A==1); %// index of entries which equal one
ind_replace = randsample(1:numel(ind_ones), numel(v)); %// index within the above
%// Or: ind_replace = randperm(numel(ind_ones));
%// ind_replace = ind_replace(1:numel(v));
A(ind_ones(ind_replace)) = v;
Note this generalizes the first part, that is, it can also be used when all entries of A equal 1.

Load values from a text file in MATLAB

I would like to load variables from a text file.
For example, my text file, varA, varB, and varC.
In MATLAB, I would like to give these variables values so that every variable is a 2x2 matrix.
So from the text file containing the above information I would get a matrix that looks like this:
[ 1 2 3 4 5 6;
1 2 3 4 5 6]
Is this possible?
I added a second example to try to make things a little clearer.
My text file, text.txt, looks like this
x1 x2 x3
In MATLAB my .m file gives the values to these variables like
x1 = [1 1; 1 1]
x2 = [2 2; 2 2]
x3 = [3 3; 3 3]
So, when I import my textfile I would get
a = (textfile)
a = [1 1 2 2 3 3 ; 1 1 2 2 3 3]
I basically try to adapt a genetic algorithm (GA) on a very huge problem (of travelling salesman problem (TSP) type). The problem is that every variable I have is a matrix and the crossover, fitness and mutation codes get pretty complicated. And I am having problems of making a random start population as well.
I would like to randomly select, let's say 30 variables, from a list with 256 so that the variable can only be picked once. Each variable however have their own specific values in a 2*2 matrix that cannot be changed.
I would like to use randperm and then put an x before every value making them variables instead of values...
If the data in the text file looks like this (strings separated by spaces):
x1 x2 x3 ...
You can read the strings into a cell array using TEXTSCAN like so:
fid = fopen('file.txt','r');
A = textscan(fid,'%s');
fclose(fid);
A = A{:};
A now stores the strings in a cell array: {'x1'; 'x2'; 'x3'; ...}. Now, to make a variable out of one of these strings and assign it a value, I would use ASSIGNIN:
assignin('base',A{1},[1 2; 1 2]);
This will create a variable x1 in the base workspace and assign it the value [1 2; 1 2]. The first argument can be either 'base' or 'caller' to create a variable in either the MATLAB base workspace or the workspace of the caller function. You would repeat this for each string name in A, giving it whatever value you want.
ALTERNATE OPTION:
This is an alternate answer to the one I gave you above. The above answer addresses the specific problem you raised in your question. This answer gives you a whole other option to potentially avoid doing things the way you were describing them in your question, and it will hopefully make things easier for you...
If I understand your problem, you basically have 256 2-by-2 matrices, and you want to randomly pick 30 of them. Each of these 2-by-2 matrices sounds like it is stored in its own variable (x1 to x256). Instead, I would suggest storing all 256 matrices in just one variable as either a 3-D array:
xArray = zeros(2,2,256); % Initialize all matrices as [0 0; 0 0]
xArray(:,:,1) = [1 1; 2 2]; % This enters a value for the first matrix
or a cell array:
xArray = cell(1,256); % Initializes an empty array of cells
xArray{1} = [1 1; 2 2]; % Enters a value for the first matrix
You would have to initialize all the values first. Then if you want to randomly pick 30 values, you can next randomize the order of either the third dimension of the 3-D array or the order of the cell array by using RANDPERM:
startOrder = 1:256; % The default order of the matrices
index = randperm(256); % Randomly order the numbers 1 to 256
xArray = xArray(:,:,index); % For a 3-d array
xArray = xArray(index); % For a cell array
Then just use the first 30 entries in xArray for your calculations (instead of the individual variables like you were before):
x = xArray(:,:,1); % Puts the first matrix from the 3-D array in x
x = xArray{1}; % Puts the first matrix from the cell array in x
You can keep repeating the use of RANDPERM to keep generating new randomized arrays of matrices. If you have to keep track of which original matrices you are using, you have to add this line after you randomize xArray:
startOrder = startOrder(index);
Now the entries of startOrder will tell you the original position a matrix was in. For example, if the first array entry in startOrder is 40, then the matrix in the first position of xArray was originally the 40th matrix you entered when you initialized xArray.
Hope this helps!