2

I have a list of strings or arrays with different length or size. I want to use the shortest string and compare with other strings by shifting the shortest string window one by one to do comparison.

Let's say I want to do addition, I have [2 1 3] as my shortest list and want to perform addition on [4 5 7 8 9]

1st addition: [2 1 3] + [4 5 7]
2nd addition: [2 1 3] + [5 7 8]
3rd addition: [2 1 3] + [7 8 9]

the example above for two arrays which i found can be solve with hankel function.

a = [2 1 3];
b = [4 5 7 8 9];

idx = hankel(1:numel(a), numel(a):numel(b));
c = bsxfun(@plus, b(idx.'), a);

and the result:

c =
     6     6    10   % [2 1 3] + [4 5 7]
     7     8    11   % [2 1 3] + [5 7 8]
     9     9    12   % [2 1 3] + [7 8 9]

but now, i want to perform for all of them and there are many combination. lets say arrays A, B, C, D, and E, so the possible addition can be A+B, A+C, A+D, A+E, B+C, B+D, B+E, C+D, C+E, D+E.

for example:

A=[2 1 3];B=[4 5 7 8 9];C=[6 9];D=[3 6 4 2 1 1];E=[4 6 9]

for A+B
 6  6  10  
 7  8  11  
 9  9  12

for A+C
 8 10
 7 12

for A+D
 5 7 7
 8 5 5
 6 3 4
 4 2 4

... and the rest

How can I do this using MATLAB? Many thanks

Divakar
  • 218,885
  • 19
  • 262
  • 358
Cina
  • 9,759
  • 4
  • 20
  • 36
  • If `a = [2 1 3]; b = [4 5 7 8 9];`, what are `A`, `B`, `C`, `D` and `E`? – Divakar Oct 15 '14 at 06:50
  • What have you tried so far? You are now just summarizing a answer to your previous question. – Nick Oct 15 '14 at 06:54
  • @Nick , the last question was contain only two arrays, now i want to extent it to more than two arrays. thx – Cina Oct 15 '14 at 07:13

2 Answers2

2

Use a custom function that works on each pair with b as the larger (in terms of number of elements) array and the core functionality being borrowed from your previous case -

function out = testfunc1(a,b) %// Shift and add arrays with different lengths

if numel(a)>numel(b) %// swap a and b,as we want b to be the larger array
    tmp = a;
    a = b;
    b = tmp;
end
out = bsxfun(@plus, b(hankel(1:numel(a), numel(a):numel(b)).'), a);
return;

Now, call this function inside arrayfun to get all those summed up arrays as cells -

%// Concatenate all variables into one cell array for processing with arrayfun
allvars = cat(1,{A},{B},{C},{D},{E}) 

%// Form all combinations between the variables
allcombs = allvars(nchoosek(1:numel(allvars),2));

%// Get summed results for each pair from all vars with one of the pairs always
%// being the first variable that represents A
out =arrayfun(@(n) testfunc1(allcombs{n,1},allcombs{n,2}), 1:size(allcombs,1),'un',0) 
celldisp(out)  %//display output

Output on run -

out{1} =
     6     6    10
     7     8    11
     9     9    12
out{2} =
     8    10
     7    12
out{3} =
     5     7     7
     8     5     5
     6     3     4
     4     2     4
out{4} =
     6     7    12
out{5} =
    10    14
    11    16
    13    17
    14    18
out{6} =
     7    11    11    10    10
    10     9     9     9    10
out{7} =
     8    11    16
     9    13    17
    11    14    18
out{8} =
     9    15
    12    13
    10    11
     8    10
     7    10
out{9} =
    10    15
    12    18
out{10} =
     7    12    13
    10    10    11
     8     8    10
     6     7    10

Thus, the cells of out represent your A+B, A+C, A+D, A+E, B+C, B+D and so on outputs respectively.

Divakar
  • 218,885
  • 19
  • 262
  • 358
  • A+E should be `6 7 12`. – Cina Oct 15 '14 at 12:58
  • @Cina Could you explain how? Maybe edit your question with that explanation? – Divakar Oct 15 '14 at 13:18
  • @Divakar: I had a small bug in the `hankel` solution. You see `hankel` returns columns, and since we are working with row vectors `a` and `b`, we have to transpose the indices before using them on `b` and applying `bsxfun` for broadcasting the addition. The bug especially showed when `a` and `b` were of the same size. Anyway like I said, the fix is easy, just move the transpose inside the parentheses :) – Amro Oct 15 '14 at 13:45
2

Here's my version:

% input arrays
A=[2 1 3]; B=[4 5 7 8 9]; C=[6 9]; D=[3 6 4 2 1 1]; E=[4 6 9];

% all possible pair combinations
pairs = nchoosek({A, B, C, D, E}, 2);

% make sure second one is the longest vector
ind = cellfun(@numel,pairs(:,1)) > cellfun(@numel,pairs(:,2));
pairs(ind,[1 2]) = pairs(ind,[2 1]);

c = cell(size(pairs,1),1);
for i=1:size(pairs,1)
    % the two vectors
    [a,b] = deal(pairs{i,:});

    % sliding window indices, and compute the sum
    idx = hankel(1:numel(a), numel(a):numel(b));
    c{i} = bsxfun(@plus, b(idx.'), a);
end

I'm reusing the solution from you previous question, and simply applying it to all possible pairs, with the result stored in a cell-array:

>> celldisp(c)
c{1} =
     6     6    10
     7     8    11
     9     9    12
c{2} =
     8    10
     7    12
c{3} =
     5     7     7
     8     5     5
     6     3     4
     4     2     4
c{4} =
     6     7    12
c{5} =
    10    14
    11    16
    13    17
    14    18
c{6} =
     7    11    11    10    10
    10     9     9     9    10
c{7} =
     8    11    16
     9    13    17
    11    14    18
c{8} =
     9    15
    12    13
    10    11
     8    10
     7    10
c{9} =
    10    15
    12    18
c{10} =
     7    12    13
    10    10    11
     8     8    10
     6     7    10

Each cell matches the following pairs (read across the rows):

>> nchoosek({'A', 'B', 'C', 'D', 'E'}, 2)
ans = 
    'A'    'B'
    'A'    'C'
    'A'    'D'
    'A'    'E'
    'B'    'C'
    'B'    'D'
    'B'    'E'
    'C'    'D'
    'C'    'E'
    'D'    'E'
Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • For some reason I thought OP wanted `A+B, A+C, A+D and A+E` only. I guess I got caught up in the outputs shown at the end of post. Do you mind if I use `nchoosek` too in my solution? :) – Divakar Oct 15 '14 at 08:21
  • @Amro Okay so edited my solution and hopefully the only thing borrowed is that `nchoosek`. – Divakar Oct 15 '14 at 08:34
  • @Amro Interesting, these arrayfun and cellfun are loopy codes anyway, but OP might prefer short/compact codes :) You had my +1, mainly because I had to borrow that `nchoosek` ;) – Divakar Oct 15 '14 at 08:50
  • @Cina: ah good catch, I edited the solution. The fix is very easy, change `bsxfun(@plus, b(idx).', a)` into `bsxfun(@plus, b(idx.'), a)` (transpose the indices before indexing not after)! – Amro Oct 15 '14 at 13:26