I have a matrix R
which has the diagonal matrix 0
and the sum of the rows should always be one. How can I update the matrix in the way that only the values which create the sum = 1
should change after iteration. How can I do it with a for loop?
R = M(1:end, 1:end-1)
R =
0.00000 0.22013 0.59930 0.00000 0.00000 0.18057
0.00000 0.00000 0.22196 0.00000 0.77804 0.00000
0.00000 0.00000 0.00000 0.60774 0.00000 0.39226
0.00000 0.00000 0.17406 0.00000 0.09191 0.00000
0.73861 0.11227 0.00000 0.00000 0.00000 0.14912
0.00000 0.26643 0.24617 0.15687 0.00000 0.00000
This is my R currently. I only want the values for example 0.22013
0.59930
and 0.18057
to change to another variation through a for loop iteration.
Newly generated array with individual rows summing to 1:
• Finding the non-zero indices in each row.
This is done by using the find()
function based on the condition (R ~= 0)
resulting in find(R ~= 0)
which returns the indices that are non-zero.
• Creating a set of random numbers that sum to 1 and are of set size equal to the amount of non-zero indices.
Using the function rand()
allows a set of numbers to be generated. To ensure that the set of numbers add up to 1 we can divide by the sum()
of the generated set. The set size can be specified by the second input parameter. In this case, we want the set size to be 1 by the number of non-zero indices in a given row. This way we can replace the values in a for-loop row by row. The call will look similar to rand(1,Number_Of_Non_Zero_Indices)
→ rand(1,length(Non_Zero_Indices)
.
• Setting the newly created set of values to replace the old non-zero values.
To replace the old non-zero values we use the indices generated by the find()
function and matrix index the given row of the matrix R
. To replace values row by row the matrix indexing is called by:
R(Row,Non_Zero_Indicies) = Random_Set;
Where,
Row
is the looping variable in the for-loop and the Non_Zero_Indicies
are the indices generated by the find()
function. This allows the resulting set to replace the corresponding indices.
%Initializing the matrix%
R = [
0.00000 0.22013 0.59930 0.00000 0.00000 0.18057;
0.00000 0.00000 0.22196 0.00000 0.77804 0.00000;
0.00000 0.00000 0.00000 0.60774 0.00000 0.39226;
0.00000 0.00000 0.17406 0.00000 0.09191 0.00000;
0.73861 0.11227 0.00000 0.00000 0.00000 0.14912;
0.00000 0.26643 0.24617 0.15687 0.00000 0.00000
];
[Number_Of_Rows,Number_Of_Columns] = size(R);
Number_Of_Iterations = 5;
Iteration = 1;
while(Iteration < Number_Of_Iterations)
for Row = 1: Number_Of_Rows
%Grabbing the row indices%
Row_Vector = R(Row,:);
%Finding non-zero indices%
Non_Zero_Indicies = find(Row_Vector ~= 0);
%Generating random set of numbers%
Random_Set = rand(1, length(Non_Zero_Indicies));
%Normalizing the set so that the values add to 1%
Normalization_Factor = sum(Random_Set);
Random_Set = Random_Set / Normalization_Factor;
%Using matrix indexing to replace the values%
R(Row,Non_Zero_Indicies) = Random_Set;
R
end
Iteration = Iteration + 1;
end
The number of newly generated variations of R
can be changed by modifying the variable Number_Of_Iterations
.
To clean up the code, the array generation script can be put into a function. This function can be iteratively called upon to generate as many variations as needed.
%Initializing the matrix%
R = [
0.00000 0.22013 0.59930 0.00000 0.00000 0.18057;
0.00000 0.00000 0.22196 0.00000 0.77804 0.00000;
0.00000 0.00000 0.00000 0.60774 0.00000 0.39226;
0.00000 0.00000 0.17406 0.00000 0.09191 0.00000;
0.73861 0.11227 0.00000 0.00000 0.00000 0.14912;
0.00000 0.26643 0.24617 0.15687 0.00000 0.00000
];
[R] = Generate_New_Array(R);
R
function [R] = Generate_New_Array(R)
[Number_Of_Rows,~] = size(R);
for Row = 1: Number_Of_Rows
%Grabbing the row indices%
Row_Vector = R(Row,:);
%Finding non-zero indices%
Non_Zero_Indicies = find(Row_Vector ~= 0);
%Generating random set of numbers%
Random_Set = rand(1, length(Non_Zero_Indicies));
%Normalizing the set so that the values add to 1%
Normalization_Factor = sum(Random_Set);
Random_Set = Random_Set / Normalization_Factor;
%Using matrix indexing to replace the values%
R(Row,Non_Zero_Indicies) = Random_Set;
end
end
Ran using MATLAB R2019b