How to obtain a Matrix?

3 views (last 30 days)
Andrea Miceli
Andrea Miceli on 30 Jun 2021
Answered: Walter Roberson on 5 Jul 2021
Hi evreyone, I am trying to obtain a matrix [n,n] by a vector [n,1] in order that the total (sum) of each row must be equal to the vector's row. See the example
vector=[ 5; 10; 3] matrix=[1,2,1,1; 2,3,4,1; 3,0,0]
There is any funciont in matlab that do this? I need that the values in the matrix are not all equal.
it's okay if it gives (2,1,2) but if it does (2,2,2) it isn't what i am looking for. It would be even better if the values in the matrix changes evrey time I run the code. For example: [1 run]-> 5= [1,1,2,0,1] | [2 run]-> 5= [1,2,2,0,0] | [3 run]-> 5= [1,3,0,0,1] and so on
Hope you can help me

Answers (4)

Matt J
Matt J on 30 Jun 2021
Edited: Matt J on 30 Jun 2021
Perhaps as follows?
vector=[ 5; 10; 3] ;
n=numel(vector);
matrix=zeros(n); %pre-allocate
s=vector;
for i=1:n
if i==n
col=s;
else
col=floor(rand*s);
end
matrix(:,i)=col;
s=max(s-col,0);
end
matrix,
matrix = 3×3
2 0 3 4 1 5 1 0 2
check=all(sum(matrix,2)==vector)
check = logical
1
  1 Comment
Matt J
Matt J on 1 Jul 2021
Matt's code with a large vector returns some numbers in the first columns, in the central columns a series of zeros and in the last column of the matrix a series of 1s.
Here is a modification that distributes the values a bit more evenly and randomly across the rows (note the attached file).
n=15;
vector=randi(3*n,n,1);
matrix=zeros(n); %pre-allocate
s=vector;
for i=1:n
if i==n
col=s;
else
factor=rand(size(s))./(sqrt(n-i));
col=floor(factor.*s);
end
matrix(:,i)=col;
s=max(s-col,0);
end
[~,perm]=sortlidx(rand(size(matrix)),2);
matrix=matrix(perm),
matrix = 15×15
2 0 2 0 1 2 9 1 1 2 5 2 5 8 4 0 2 0 0 4 2 0 2 3 1 1 2 1 5 2 0 3 1 2 1 0 1 1 0 1 2 0 1 3 3 2 3 2 3 0 6 5 0 4 3 1 5 0 1 0 1 0 0 4 3 1 1 1 4 4 0 1 2 1 1 1 1 5 6 6 1 1 1 4 1 4 0 1 2 2 0 2 2 1 0 2 0 0 0 2 2 0 0 1 1 4 4 8 1 4 1 2 3 1 1 2 1 6 1 1 6 0 1 0 1 5 2 6 3 7 3 2 1 1 0 1 0 0 0 0 0 0 0 1 0 1 2 1 0 1
check=all(sum(matrix,2)==vector)
check = logical
1

Sign in to comment.


Image Analyst
Image Analyst on 1 Jul 2021
I don't believe it's a common enough thing to want to do that there is a built in function for it so you'll have to build it yourself.
If you're not restricting it to integers, this works:
vector = [5; 10; 3] % Column vector
matrix = repmat(vector', [length(vector), 1])
percentages = [0.5, 0.3, 0.2] % Fractions of number to appear in each row.
matrix(1,:) = matrix(1,:) * percentages(1);
matrix(2,:) = matrix(2,:) * percentages(2);
matrix(3,:) = matrix(3,:) * percentages(3)
matrix =
2.5 5 1.5
1.5 3 0.9
1 2 0.6

Andrea Miceli
Andrea Miceli on 1 Jul 2021
Both your code and Matt's are very good, but the problem is that they really work on small vectors.
Matt's code with a large vector returns some numbers in the first columns, in the central columns a series of zeros and in the last column of the matrix a series of 1s.
Images Analyst's code takes a lot of work to calculate the matrix due to the fact that the "percentages" step is hand-made.
Anyway a big thank you to both of you :)
  4 Comments
Andrea Miceli
Andrea Miceli on 5 Jul 2021
I don't have any formula, i can select which method I want, so actually now I am trying to fit your method with my data (I am going to use 2) random portions. Thank you so much. Both of you were really helful

Sign in to comment.


Walter Roberson
Walter Roberson on 5 Jul 2021
https://www.mathworks.com/matlabcentral/answers/327656-conditional-random-number-generation#answer_257296 has code.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!