I have the following computation I'd like to vectorize in matlab.
I have a N x 3 array, call it a.
I have a 4 x 1 cell array of function handles, call them b.
I would like to create an Nx4 matrix c, such that c(i,j) = b{j}(a(i,:).
b is actually an array, but I don't know how to write down my representation for c in a format that matlab would understand that uses a matrix.
If your function handles work on arrays (i.e. b{j}(a) returns a Nx1 array in your example), you can use CELLFUN and CELL2MAT to generate your output array:
c = cell2mat( cellfun( #(bFun)bFun(a),b,'UniformOutput',false) );
If your function handles only work on individual rows (i.e. b{j} needs to be applied to every row of a separately, you can throw ARRAYFUN into the mix (readability suffers a bit though; basically, you're applying each element of b via cellfun to each row of a via arrayfun):
c = cell2mat(...
cellfun( #(bFun)arrayfun(...
#(row)bFun(a(row,:)),1:size(a,1)),...
b,'UniformOutput',false) ...
);
pdist2 almost solves the problem above. Probably someone more clever than me can figure out how to shoe horn the two together.
Related
I am working on matlab with a matrix. I would like to reproduce this matrix and apply sum for elements in rows.
I have two vectors defined by this code:
unitsvector=1:5;
reordervector=1:3;
Then, I create an empty matrix to store the values:
resultvec=zeros(size(unitsvector,2)*size(reordervector,2),3);
Finally, here is the loop I use but it is not working:
for a=1:length(resultvec)
for b=reordervector
for c=unitsvector
resultvec(a,1)=b;
resultvec(a,2)=c;
resultvec(a,3)=b+c;
end
end
end
How could I reproduce this matrix in matlab. Thanks for your help.
You can use meshgrid for this without a for loop.
[a,b] = meshgrid(1:5,1:3);
M = [a(:) b(:)];
M(:,3) = sum(M,2); % Create third column by summing first two
Why are you looping at all? sum actually has vector support; a simple resultvec = [a(:,1),a(:,2),sum(a,2)] would work.
As to your code: of course it doesn't work. What do you expect to be the contents of a? You create a as a loop index, which runs over the range 1:length(resultvec). Ergo, within each loop iteration a is a scalar. You try to call it like it is a three-element vector. Nor do you define b and c. This might be possible in R, judging where you're coming from, but not in MATLAB.
Given two 100x3 matrix A and B. How do I multiple them in Matlab without loop such that the output matrix is (sorry for the bad format).
a11*b11 a12*b12 a13*b13
a21*b21 a22*b22 a23*b23
...
If we say output matrix is C, then: C = A.*B
use a dot for element wise multiplication A.*B
MATLAB question:
I have an array A(2,2,2) that is three-dimensional. I would like to define a 2x2 array as a subarray of A, as follows:
B = A(1,:,:).
That is, we are simply projecting on the first component. But matlab will now treat this 2x2 matrix as a 1x2x2 array instead, so that I can't do certain things (like multiply by another 2x2 matrix).
How do I get B as a 2x2 subarray of A?
If you think about a skyscraper, your A(1,:,:) is taking the first floor out and this operation inevitably happens across the 3rd dimension.
You can use reshape(), squeeze() or permute() to get rid of the singleton dimension:
reshape(A(1,:,:),2,2)
squeeze(A(1,:,:))
permute(A(1,:,:),[2,3,1])
squeeze() pretty much does all the job by itself, however it is not an inbuilt function and in fact uses reshape(). The other two alternatives are expected to be faster.
You'd want to use the function squeeze which removes the singleton dimensions:
B = squeeze(A(1,:,:))
Let's say I have two arrays X and Y and I need a matrix M(i, j) = some_func(X(i), Y(j)). How can I get that without using loops?
The best answer is to use bsxfun, IF it is an option. According to the help for bsxfun, it will work on any general dyadic function, as long as:
FUNC can also be a handle to any binary element-wise function not listed
above. A binary element-wise function in the form of C = FUNC(A,B)
accepts arrays A and B of arbitrary but equal size and returns output
of the same size. Each element in the output array C is the result
of an operation on the corresponding elements of A and B only. FUNC must
also support scalar expansion, such that if A or B is a scalar, C is the
result of applying the scalar to every element in the other input array.
If your function accepts only scalar input, then loops are the simple alternative.
It's difficult to answer your vague question, and it ultimately depends on your function. What you can do is use meshgrid and then perform your operation, typically with use of the dot operator
e.g.
x = 1:5;
y = 1:3;
[X,Y] = meshgrid (x,y)
M = X.^Y;
I am doing my dissertation now. I stuck with a integral. My function is defined as
myfun =(exp(t*Q)*V*x)(j);
where Q and V are a matrix (n*n), x is a vector which elements are 1, then after calculation we get the j_th element of that vector then I need to integrate the function against t.
I want to use the quad in the matlab. However the point is that it will report the inner matrix is not the same size. Since A here is not a number ?....
How can I do this. Otherwise I could only write a loop against t itself, which is extremely slow.
Thanks
You can use SUBSREF for this (you still neet to loop over all j's, though):
myfunOfT = #(t)(subsref(exp(t*Q)*V*x,struct('type','()','subs',j);
This returns the value of the jth element of the array at time t.