Reputation: 75
Is there any function in Matlab that can take two vectors (not necessarily of the same size) and apply a binary function on every pair of the vector's elements resulting in a matrix n1xn2, where n1 and n2 are the lengths of the input vectors?
Something similar to pdist2, but with arbitrary function pointer instead of the distance function.
Example usage:
v1 = [1, 2, 3]
v2 = [2, 3]
Apply(@plus, v1, v2) -> [3, 4; 4, 5; 5, 6];
Note: although, the example is numerical, the actual vectors I need to work with are arrays of cells each containing a string (all strings have equal length). The binary function takes two strings and returns a scalar, for example - strcmp.
Upvotes: 2
Views: 502
Reputation: 30579
An answer to the OP's last comment (very different from the content of the question) would be the following:
>> v1 = [{'one'}, {'two'}]; v2 = [{'two'}, {'three'}];
>> cellfun(@strcmp,repmat(v1',1,size(v2,2)),repmat(v2,size(v1,2),1))
ans =
0 0
1 0
For the example numeric data and the plus operation in the question, that is solved by:
>> v1 = [1, 2, 3]; v2 = [2, 3];
>> bsxfun(@plus,v1',v2)
ans =
3 4
4 5
5 6
However, I think the answer to the string concatenation problem is answered well by Luis Mendo.
In general, to do an operation for all pairs, bsxfun
should be your go-to function for numeric arrays. For cells, strings, and other non-POD types, consider combinations of repmat
, arrayfun
and cellfun
. It's hard to be more specific without a more specific question.
Upvotes: 0
Reputation: 112659
You can achieve that with ndgrid
and arrayfun
. Consider the following example data (cell arrays of strings):
v1 = {'aa','bb','cc'};
v2 = {'1','22'};
and example function (string concatenation):
fun = @(str1, str2) [str1 str2]
Then:
M = length(v1);
N = length(v2);
[ii jj] = ndgrid(1:M, 1:N);
reshape(arrayfun(@(k) fun(v1{ii(k)},v2{jj(k)}) , 1:M*N, 'uni', false), M,N)
gives the desired result:
ans =
'aa1' 'aa22'
'bb1' 'bb22'
'cc1' 'cc22'
In the general case, simply define v1
, v2
and fun
as needed.
Upvotes: 1
Reputation: 14939
This one works on the example data:
repmat(v2,numel(v1),1)+[v1(:), v1(:)]
ans =
3 4
4 5
5 6
Try something like this if numel(v2) ~= 2
(still only for the numerical example you have provided):
repmat(v2,numel(v1),1)+repmat(v1(:),1,numel(v2))
Upvotes: 0