How to obtain a Matrix?

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

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

0 votes

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

You gave us little guidance or restrictions on the problem. You didn't say whether the numbers had to be intergers or not. You didn't say how large n might be. You're not saying how to computer percentages. If you don't want to say what they are, then you could just get random percentages like this:
percentages = rand(1, length(vector))% Fractions of number to appear in each row are random.
percentages = percentages / sum(percentages); % Make sure they sum to 1.
I'm not sure if you consider those 2 lines of code "a lot of work" or "hand made". Essentially every line of code in the program is handmade in a sense. But this way computes the percentages randomly instead of using predetermined percentages, if that's what you want. And of course the last 3 lines could be done in a loop if your n is larger than 3. For only 3 doing it explictly (like I did) or using a for loop both take 3 lines of code (if you're wanting to minimize lines of code).
You can "thank" us by clicking the "Vote" icons to award "reputation points.". Thanks in advance.
Anyway, you never shared the use case for this. Presumably it's not your homework since I'm sure your professor doesn't want you turning in other people's solutions as your own, but what is it for? Why do you want to do this uncommon thing? If you shared that we might give different answers.
Andrea Miceli
Andrea Miceli on 1 Jul 2021
Edited: Andrea Miceli on 1 Jul 2021
I apologize, if my comment was intended as an offense, it was definitely not my intention. I just wanted to leave feedback for a possible future user interested in the same process, it didn't want to be a criticism of your codes at all. You are right that I have given few indications, but I did it because I simply needed the reasoning behind the development of this procedure.
I am developing a study on the distribution of financial shocks in interbank systems (for my thesis) and to do this I need to create a network. To create this network I decided to use a graph and for this I need an adjacency matrix (I know that there are functions to create an adjacency matrix, but I have not been able to master them correctly). The goal would be to take the value contained in each row of the vector and distribute it in the same row of the adjacency matrix, but in different columns of the adjacency matrix (as I shown in the example above), in order to form the edge weights that my graph needs.
No offense taken - just trying to figure out what you want and if either what Matt or I did was what you want or need? From your explanation it sounds like floating point ratios of the numbers is fine - they don't need to be integers like Matt assumed (a logical assumption given your example). So now you can take continuous/floating point values but the question is how to pick the component numbers that sum up to your desired number. Of course, there is an infinite number of number sets that can sum up to the desired number if they don't need to be integers. So I did it two ways: (1) just use predetermined values (proportions), and (2) use random proportions. They both worked, but do you prefer one over the other? If you don't like either, then why not -- what are they lacking? And what method for picking the component numbers would you prefer instead? Do you have some formula for picking the proportions?
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

0 votes

https://www.mathworks.com/matlabcentral/answers/327656-conditional-random-number-generation#answer_257296 has code.

Categories

Asked:

on 30 Jun 2021

Answered:

on 5 Jul 2021

Community Treasure Hunt

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

Start Hunting!