Cell manipulation (swapping, combining and converting to an array)
Show older comments
First assume that we have this matrix
[ 9 -2 0]
A= [-2 9 -2]
[ 0 -2 9]
The goal is to store all the non-zero elements of A and its associated column index (col_ind). However for every row I want to store the value of the diagonal first.
So the end result is something like this:
val= [9 -2 9 -2 -2 9 -2]
col_ind= [1 2 2 1 3 3 2]
My approach is to first store the col_ind and val in a 1x3 cell.
{val} = [9;-2] [-2;9;-2] [-2;9]
{col_ind}= [1,2] [0,0,1,2,3] [0,0,0,0,0,2,3]
Issue 1: How do I get rid of the zeroes in
[0,0,1,2,3] [0,0,0,0,0,2,3] and get this
{col_ind}= [1,2] [1,2,3] [2,3]
From this, I can swap the elements in doubles in {val} so that 9 is always the leading entry for each.
Issue 2: How do I swap the entries in each double and also make sure that the column indices are swapped appropriately such that I will get this:
{val} = [9;-2] [9;-2;-2] [9;-2]
{col_ind}= [1,2] [2,1,3] [3,2]
How can the function sort be used in this case?
Issue 3: How do I merge the cells together to finally have this, an array of:
col_ind = [1 2 2 1 3 3 2]
Here is my code so far:
clear all
%Consider a 3x3 matrix
A= [ 9 -2 0; -2 9 -2; 0 -2 9];
%initialise arrays:
n = 3.0;
CI = zeros(1,1); %column index
V = zeros(1,1); %value in the matrix
index = 1.0;
counter=zeros(n,1);
val=cell(1,n);
col_ind = cell(1,n);
for t=1:n
val{t}=V;
col_ind{t}=V;
end
for k = 1:n %row 1 to n
for j = 1:n %column 1 to n
if A(k,j)~=0
%CI(index)=j;
col_ind{k}(index)=j;
%V(index)=A(k,j);
index = index + 1.0;
end
val{k}= nonzeros(A(k,:));
end
end
Accepted Answer
More Answers (1)
Guillaume
on 8 Feb 2017
Another option, assuming that there's always a non-zero value on the diagonal (or the whole row is 0):
[col_ind, row_ind, val] = find(A');
rowstart = find(diff([0; row_ind]) ==1); %find location of 1st element of row
diagidx = find(col_ind == row_ind); %find location of diagonal element
col_ind([rowstart; diagidx]) = col_ind([rowstart; diagidx]); %and swap
val([rowstart; diagidx]) = val([rowstart; diagidx]); %and swap in val as well
Note that the above swap the diagonal with the 1st non-zero element of the row (in both val and col_ind). It does not move the diagonal first while keeping the order of the rest of the elements of the row (i.e. it goes from [1 2 3 d 5 6 7] to [d 2 3 1 5 6 7], not [d 1 2 3 5 6 7]). You did not say anything about the order of the other elements, so I assumed it's not an issue.
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!