user3120554
user3120554

Reputation: 681

Matlab: reshaping a matrix into a 1D array with overlapping elements added together

Here is an example matrix:

x=[1,2,3,4,5;6,7,8,9,10;11,12,13,14,15]'; % 1:5 in 1st column, 6:10 in 2nd etc

so I have:

x=
1 6  11
2 7  12
3 8  13
4 9  14
5 10 15

I want to overlap the upper half of elements of a given column (not including mid element) with the lower half of the previous column, adding the elements in the overlap. The first and last column will obviously be the exception (first column doesn't have a previous column, and nothing to add to last column)

in the simplistic example above, I have rewritten the line to show what numbers to overlap for clarity:

x=[1,2,3,4,5;
         6,7,8,9,10;
               11,12,13,14,15]';

hence, I want the result to be:

y=[1;2;3;4+6;5+7;8;9+11;10+12;13;14;15];

Now, this is just a very simple example. The resulting code needs to scale well/run efficiently with big data. Likely size of the matrix will be something like 120000x600 and I think the resulting 1D array will be something like 37000000x1

Upvotes: 3

Views: 733

Answers (4)

Luis Mendo
Luis Mendo

Reputation: 112749

Answer to original question (add shifted rows):

This can be done as follows:

  1. Generate an indexing vector (ind) such that entries of x to be summed have the same index. This can be done with bsxfun. The index can be computed once and reused for different x vectors (the index doesn't depend on x).
  2. Use that indexing vector to do the sum with accumarray:

Code:

n = ceil(size(x,2)/2);
ind = bsxfun(@plus, 1:size(x,2), (0:size(x,1)-1).'*n); %'// step 1. Valid for any x
y = accumarray(ind(:), x(:));                          % // step 2. Depends on x

Answer to edited question (add shifted columns):

Transpose x and proceed as above:

x = x.';
n = ceil(size(x,2)/2);
ind = bsxfun(@plus, 1:size(x,2), (0:size(x,1)-1).'*n);for any x
y = accumarray(ind(:), x(:));

Upvotes: 5

Mohsen Nosratinia
Mohsen Nosratinia

Reputation: 9864

Probably not the most scalable solution, but likely a readable and intuitive one:

% Split the matrix into three parts
left  = x(:,1:floor(end/2));
mid   = x(:,floor(end/2)+1:ceil(end/2));
right = x(:,ceil(end/2)+1:end);

% Extend the middle part by one, note that this works even if mid is empty
mid(end+1,:) = nan;

% Construct a new matrix by summing up left and right parts
X = [left(1,:); ...
     left(2:end,:) + right(1:end-1,:); ...
     right(end,:)];

% Add the midpoints back
X=[X, mid].';

% Reshape into vector and remove the possible extra mid point 
y = X(1:end-~isempty(mid));

Upvotes: 0

Thomas Sablik
Thomas Sablik

Reputation: 16448

The addititions can be calculated with one matrix matrix addition and after this you reorder your result.

The matrix matrix addition has the form

x = [1  2  3  4  5;
     6  7  8  9  10;
     11 12 13 14 15];

A = [4 5; 9 10] + [6 7; 11 12]

The first and the last rows and the middle column are unchanged. This yields the following code:

x=[1,2,3,4,5;6,7,8,9,10;11,12,13,14,15]';

x = x.';

n = ceil(size(x,2)/2);
m = floor(size(x,2)/2);

A = [x(1:(end-1),(m+1):n) x(2:end,1:m)+x(1:(end-1),(n+1):end)]';

y = [x(1,1:m) A(:)' x(end,(m+1):end)];

The result is y = 1 2 3 10 12 8 20 22 13 14 15

It needs 1.3 seconds for x=rand(120000,600)

Upvotes: 1

Divakar
Divakar

Reputation: 221664

This could be one approach -

%// Get size
[n,m] = size(x)

%// Indices of first overlapping elements and its length
first_overlap = ceil(n/2)+1:n
overlap_len = numel(first_overlap)

%// Store the last elements of overlapping length to be appended at final stage
rem_ele = x(end-numel(first_overlap)+1:end)

%// Indices of overlapping elements across all columns
idx = bsxfun(@plus,first_overlap(:),[0:m-2]*n)

%// Do summations of overlaps and store back tto the next group of overlaps
x(idx(:)+overlap_len) = x(idx(:)) + x(idx(:)+overlap_len)

%// Remove elements from the previous overlaps
x(end-overlap_len+1:end,:)=[]

%// Output array after appending rem_ele to column vector version of modified x
out = [x(:) ; rem_ele(:)]

Upvotes: 0

Related Questions