MATLAB: Rearrange elements in an array based on another array

arrayMATLAB

Hi,
given the following matrix
V=
[12 11 9 8 10 6 8 7 9 5 4 6 9;
8 10 7 8 9 8 4 4 12 12 6 6 10]
and
M=
[0 23 10 1 0 0 12 0 23 0 0 0 0;
0 23 11 0 0 0 15 0 20 0 0 0 0]
I want to rearrange the ROWS of M matrix on the basis of V.
Considering just the first rows of V and M
12 11 9 8 10 6 8 7 9 5 4 6 9
0 23 10 1 0 0 12 0 23 0 0 0 0
the cumulative sum of the M row is (23+11+1+12+23)=70
Now in the zero places of M row just put the value in the same column of row V, and put 0 in the non zero values, obtaining
12 0 0 0 10 6 0 7 0 5 4 6 9 %SUM 59
the cumulative sum of this new vector is 59. So from now on we want to put 1 in the zeros places till we reach 70. So
12 1 1 1 10 6 1 7 1 5 4 6 9 %SUM 64
Then again
12 2 2 2 10 6 2 7 2 5 4 6 9 %SUM 69
And finally
12 3 2 2 10 6 2 7 2 5 4 6 9 %SUM 70
Now the cumulative sum is the same as the beginning (70)
So the basic idea is to put in the zeros places of M the value of the corresponding places in V, and then, try to reduce as much as possible the other places (that were the no zero places in M)
May someone help me with this task?

Best Answer

s = sum(M,2);
v = V.*(M == 0);
ss = s - sum(v,2);
lo = ss > 0;
n = sum(v == 0,2);
a = fix(ss./n);
b = mod(ss,n);
add = arrayfun(@(n,a,b)ones(n,1)*a + [ones(b,1);zeros(n-b,1)],n,a,b,'un',0);
vv = v(ss > 0,:)';
vv(vv == 0) = cat(1,add{lo});
v(lo,:) = vv';