# How to obtain a Matrix?

3 views (last 30 days)
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

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
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

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 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 :)
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

Walter Roberson on 5 Jul 2021