The trick is to use sub2ind, and remember that MATLAB operates down columns first, so it helps to transpose the input matrix. Note in the code below the indices idx, idc, idr, and idi refer to this transposed matrix.
>> M = [1,2;2,3;3,4;1,3;1,4]
M =
1 2
2 3
3 4
1 3
1 4
>> tmp = M.'; % because MATLAB operates down columns
>> idx = tmp~=1; % input logical indices
>> [~,idc] = find(idx); % output column indices
>> idr = tmp(idx)-1; % output row indices
>> mat = zeros(max([idr,idc])); % preallocate the output matrix
>> idi = sub2ind(size(mat),idr,idc); % output linear indices
>> tmp(1,:) = -tmp(1,:); % first row negative (first column of M)
>> mat(idi) = tmp(idx); % assign input values to output matrix
>> mat.' % all values present and correct!
ans =
2 0 0
-2 3 0
0 -3 4
0 3 0
0 0 4
At this point you could simply use repelem or the method below:
>> mat = reshape(repmat(mat.',2,1),size(mat,2),[])
mat =
2 2 0 0 0 0
-2 -2 3 3 0 0
0 0 -3 -3 4 4
0 0 3 3 0 0
0 0 0 0 4 4
Here I tested the code on your other sample matrix:
>> M = [1,3;2,3;2,4;4,1;2,1]
M =
1 3
2 3
2 4
4 1
2 1
...
>> mat = reshape(...)
mat =
0 0 3 3 0 0
-2 -2 3 3 0 0
-2 -2 0 0 4 4
0 0 0 0 -4 -4
-2 -2 0 0 0 0
which can be compared against your requested output:
>> [ 0 0 3 3 0 0 ; -2 -2 3 3 0 0 ; -2 -2 0 0 4 4 ; 0 0 0 0 -4 -4 ; -2 -2 0 0 0 0 ]
ans =
0 0 3 3 0 0
-2 -2 3 3 0 0
-2 -2 0 0 4 4
0 0 0 0 -4 -4
-2 -2 0 0 0 0
Best Answer
Where M is your matrix:
or