1

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.

Jan
  • 2,025
  • 17
  • 27
Amra Feta
  • 21
  • 4
  • Welcom to stackoverflow! What did you try so far, have you been searching through stackoverflow already looking for examples of for loops on matrices in matlab? – Jan Oct 26 '20 at 11:17
  • Hi and welcome! Please elaborate more on what are you strugling for. You don't know how to do a for loop? How to acces de matrix? Or what? It is not clear what your problem is. – Òscar Raya Oct 26 '20 at 11:35

1 Answers1

1

In MATLAB:

Newly generated array with individual rows summing to 1: Newly Generated Array/Matrix

This solution focuses on three main areas:

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

Full Script:

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

Functional Form:

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.

Function Call:

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

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

MichaelTr7
  • 4,737
  • 2
  • 6
  • 21
  • Thank you so much for your effort! This is working smoothly for my example. I already have created my matrix and the diagonals but this was the only step I was struggling. I appreciate it. – Amra Feta Nov 02 '20 at 18:59
  • 1
    @AmraFeta No problem, happy to help. :) Please consider accepting the answer/upvoting if this has sufficiently answered your question. – MichaelTr7 Nov 02 '20 at 19:08