how to create array of random normalize number? - arrays

i want to create a matrix that each row of the matrix have 7 real random number in [0,1] and the sum of number in each rows should be equal to 1.
this matrix have 100 rows and 7 columns. how can i do it?
at first ,i create an array with 1 row and 7 columns. then write the code as bellow. i try normal the number in the rows but sum of each row became more than 1.how can i fix it? thank for taking your time.
a = rand(1,7);
for i=1:7
a(i) = a(i)/sum(a);
end
sum(a)

For 100 by 7, you can use bsxfun:
a = rand(100,7);
a = bsxfun(#rdivide,a.',sum(a.')).';
Here the sum of each row = 1

The problem is that by using a for-loop, you're changing the sum of the vector every loop iteration. You should take advantage of MATLAB's ability to act on whole matrices at once:
a = rand(1,7);
a = a./sum(a);

Related

How to repeat calculation for every value in an array and store the vector of each result in a new array in MATLAB [duplicate]

I've just started using for loops in matlab in programming class and the basic stuff is doing me fine, However I've been asked to "Use loops to create a 3 x 5 matrix in which the value of each element is its row number to the power of its column number divided by the sum of its row number and column number for example the value of element (2,3) is (2^3 / 2+3) = 1.6
So what sort of looping do I need to use to enable me to start new lines to form a matrix?
Since you need to know the row and column numbers (and only because you have to use loops), for-loops are a natural choice. This is because a for-loop will automatically keep track of your row and column number for you if you set it up right. More specifically, you want a nested for loop, i.e. one for loop within another. The outer loop might loop through the rows and the inner loop through the columns for example.
As for starting new lines in a matrix, this is extremely bad practice to do in a loop. You should rather pre-allocate your matrix. This will have a major performance impact on your code. Pre-allocation is most commonly done using the zeros function.
e.g.
num_rows = 3;
num_cols = 5;
M = zeros(num_rows,num_cols); %// Preallocation of memory so you don't grow your matrix in your loop
for row = 1:num_rows
for col = 1:num_cols
M(row,col) = (row^col)/(row+col);
end
end
But the most efficient way to do it is probably not to use loops at all but do it in one shot using ndgrid:
[R, C] = ndgrid(1:num_rows, 1:num_cols);
M = (R.^C)./(R+C);
The command bsxfun is very helpful for such problems. It will do all the looping and preallocation for you.
eg:
bsxfun(#(x,y) x.^y./(x+y), (1:3)', 1:5)

Adding multiple rows in Array

I have an array A size of 16X16 and I want to add first 3 rows out of 16 in A. What is the most efficient solution in MATLAB?
I tried this code but this is not efficient because I want to extend it for large arrays:
filename = 'n1.txt';
B = importdata(filename);
i = 1;
D = B(i,:)+ B(i+1,:)+ B(i+2,:);
For example, if I want to extend this for an array of size 256x256 and I want to extract 100 rows and add them, how I will do this?
A(1:3,:);%// first three rows.
This uses the standard indices of matrix notation. Check Luis's answer I linked for the full explanation on indices in all forms. For summing things:
B = A(1:100,:);%// first 100 rows
C = sum(B,1);%// sum per column
D = sum(B,2);%// sum per row
E = sum(B(:));%// sum all elements, rows and columns, to a single scalar

Repeating a vector function and storing into matrix

I have a function which creates a row vector(N) up to a specified number of N columns. This vector is generated by have the next column add a random integer between 1 and 5 to the previous column and keeps on going until column N. However, I wish to generate the function vector(200) 500 times, where each row vector is randomly generated, and then store each of these vector into a matrix of size 500x200.
I am currently a beginner and I'm just testing Matlab out.
What I tried to do is:
for r=1:500
row(r) = vector(200)
mat(r, :) = row(r)
end
However this does not seem to work. Any help or suggestion will be appreciated.
Thanks!
Assuming the first column is also a random number between 1 and 5, you can do this
result = cumsum(randi(5, 500, 200), 2);
How it works: randi(5, 500, 200) generates 500x200 random integers between 1 and 5; and cumsum(..., 2) gives the cumulative sum along each row.

Is there a better/faster way of randomly shuffling a matrix in MATLAB?

In MATLAB, I am using the shake.m function (http://www.mathworks.com/matlabcentral/fileexchange/10067-shake) to randomly shuffle each column. For example:
a = [1 2 3; 4 5 6; 7 8 9]
a =
1 2 3
4 5 6
7 8 9
b = shake(a)
b =
7 8 6
1 5 9
4 2 3
This function does exactly what I want, however my columns are very long (>10,000,000) and so this takes a long time to run. Does anyone know of a faster way of achieving this? I have tried shaking each column vector separately but this isn't faster. Thanks!
You can use randperm like this, but I don't know if it will be any faster than shake:
[m,n]=size(a)
for c = 1:n
a(randperm(m),c) = a(:,c);
end
Or you can try switch the randperm around to see which is faster (should produce the same result):
[m,n]=size(a)
for c = 1:n
a(:,c) = a(randperm(m),c);
end
Otherwise how many rows do you have? If you have far fewer rows than columns, it's possible that we can assume each permutation will be repeated, so what about something like this:
[m,n]=size(a)
cols = randperm(n);
k = 5; %//This is a parameter you'll need to tweak...
set_size = floor(n/k);
for set = 1:set_size:n
set_cols = cols(set:(set+set_size-1))
a(:,set_cols) = a(randperm(m), set_cols);
end
which would massively reduce the number of calls to randperm. Breaking it up into k equal sized sets might not be optimal though, you might want to add some randomness to that as well. The basic idea here though is that there will only be factorial(m) different orderings, and if m is much smaller than n (e.g. m=5, n=100000 like your data), then these orderings will be repeated naturally. So instead of letting that occur by itself, rather manage the process and reduce the calls to randperm which would be producing the same result anyway.
Here's a simple vectorized approach. Note that it creates an auxiliary matrix (ind) the same size as a, so depending on your memory it may be usable or not.
[~, ind] = sort(rand(size(a))); %// create a random sorting for each column
b = a(bsxfun(#plus, ind, 0:size(a,1):numel(a)-1)); %// convert to linear index
Obtain shuffled indices using randperm
idx = randperm(size(a,1));
Use the indices to shuffle the vector:
m = size(a,1);
for i=1:m
b(:,i) = a(randperm(m,:);
end
Look at this answer: Matlab: How to random shuffle columns of matrix
Here's a no-loop approach as it processes all indices at once and I believe this is as random as one could get given the requirements of shuffling among each column only.
Code
%// Get sizes
[m,n] = size(a);
%// Create an array of randomly placed sequential indices from 1 to numel(a)
rand_idx = randperm(m*n);
%// segregate those indices into rows and cols for the size of input data, a
col = ceil(rand_idx/m);
row = rem(rand_idx,m);
row(row==0)=m;
%// Sort both these row and col indices based on col, such that we have col
%// as 1,1,1,1 ...2,2,2,....3,3,3,3 and so on, which would represent per col
%// indices for the input data. Use these indices to linearly index into a
[scol,ind1] = sort(col);
a(1:m*n) = a((scol-1)*m + row(ind1))
Final output is obtained in a itself.

Turning an array in to a matrix in MATLAB

I need to turn a large array into a matrix in the following way: to take the first m entries of the array and make that the 1st row of the matrix.
For example: if I had an array that was 100 entries long, the corresponding matrix would be 10 rows and each row would be 10 entries of the array with the order preserved.
I've tried the following code:
rows = 10
row_length = 10
a = randi(1,100);
x = zeros(rows,row_length)
for i=1:rows
x(i) = a(i:i+row_length)
end
but with no luck. I'm stuck on how to slide the window along by row_length so that i will start from row_length+1 in the second (and subsequent) iterations of the loop.
The best way to do it is to use Matlab's reshape function:
reshape(a,row_length,[]).'
It will reshape by first assigning down the columns which is why I transpose at the end (i.e. .')
However just for the sake of your learning, this is how you could have done it your way:
rows = 10
row_length = 10
a = rand(1,100)
x = zeros(rows,row_length)
for i=1:row_length:rows*row_length %// use two colons here, the number between them is the step size
x(i:i+row_length-1) = a(i:i+row_length-1) %// You need to assign to 10 elements on the left hand side as well!
end

Resources