Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using arrayfun to apply two arguments of a function on every combination

Let i = [1 2] and j = [3 5]. Now in octave:

arrayfun(@(x,y) x+y,i,j)

we get [4 7]. But I want to apply the function on the combinations of i vs. j to get [i(1)+j(1) i(1)+j(2) i(2)+j(1) i(2)+j(2)]=[4 6 5 7].

How do I accomplish this? I know I can go with for-loopsl but I want vectorized-code because it's faster.

like image 645
niceman Avatar asked May 22 '26 16:05

niceman


1 Answers

In Octave, for finding summations between two vectors, you can use a truly vectorized approach with broadcasting like so -

out = reshape(ii(:).' + jj(:),[],1)

Here's a runtime test on ideone for the input vectors of size 1 x 100 each -

-------------------- With FOR-LOOP
Elapsed time is 0.148444 seconds.
-------------------- With BROADCASTING
Elapsed time is 0.00038299 seconds.

If you want to keep it generic to accommodate operations other than just summations, you can use anonymous functions like so -

func1 = @(I,J) I+J;
out = reshape(func1(ii,jj.'),1,[])

In MATLAB, you could accomplish the same with two bsxfun alternatives as listed next.

I. bsxfun with Anonymous Function -

func1 = @(I,J) I+J;
out = reshape(bsxfun(func1,ii(:).',jj(:)),1,[]);

II. bsxfun with Built-in @plus -

out = reshape(bsxfun(@plus,ii(:).',jj(:)),1,[]);

With the input vectors of size 1 x 10000 each, the runtimes at my end were -

-------------------- With FOR-LOOP
Elapsed time is 1.193941 seconds.
-------------------- With BSXFUN ANONYMOUS
Elapsed time is 0.252825 seconds.
-------------------- With BSXFUN BUILTIN
Elapsed time is 0.215066 seconds.
like image 95
Divakar Avatar answered May 25 '26 15:05

Divakar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!