I would like to vectorize the following loop:
for I=1:N
x = f(x);
end
with f being a custom function, i.e. an anonymous function.
Is there a command like arrayfun that allows this?
edit: May be vectorization is the wrong word here, and rather optimization should be used.
I don't check the code, but maybe:
x = arrayfun(#(y) f(x), 1:N);
With arrayfun you can take each element of the vector you passed as parameter. In the example above, y refers to each element of the vector 1:N, which also represents the index of the for loop you posted as example. In your for loop you do not use the index so you can do the same in the arrayfun and iterate over a vector doing what you want inside: f(x). Finally you can assign the output to x. Possibly, with the arrayfun way you retrieve an output x of length N with the result of each f(x) in the iterations. With the for loop you overwrite in each iteration the value of x.
Hope you help and sorry for my english.
Related
Hello I need help plotting the below equation in matlab.
v=10.0004+10.229*e^(-3*t)*sin(5.196*t-257.856)
here is what I have but I keep getting an error:
t=[0:0.1:2];
v=10.0004+10.229*exp(t)*sin(5.196*t+257.856);
plot(t,v)
Error using *
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the
number of rows in the second matrix. To perform elementwise multiplication, use '.*'.
Error in example (line 2)
v=10.0004+10.229*exp(t)*sin(5.196*t+257.856);
Because t is a matrix, you cannot simply input it as you would a single variable. You have to access each value individually and calculate a corresponding v, then you store that value and move on. Rinse and repeat for each value.
This can be visualized with a for loop. Get the length of your time variable, which will determine how many values you need to calculate, then let the loop run for the corresponding number of elements. Make sure the loop counter is also used to index each element in v.
t = 0:0.1:2 ;
%For each element (n) in t, create a corresponding one of v.
for n = 1:length(t)
v(n) = 10.0004+10.229*exp(t(n))*sin(5.196*t(n)+257.856);
end
plot(t,v)
As we can interpret from the loop, there is a need to do element-wise (good keyword to remember) multiplication. In other languages, you might HAVE to use the loop method. Luckily in Matlab there is a dedicated operator for this '.*'. Therefore in Matlab you could simply modify your code as follows:
t=[0:0.1:2];
v=10.0004+10.229.*exp(t).*sin(5.196.*t+257.856);
plot(t,v)
Either method gives you the desired plot. The first I included to illustrate the underlying logic of what you're looking to do, and the second to simply it with Matlab's syntax. Hope this helps guide you in the future.
Best of luck out there.
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.
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.
Say I have a function calculateStuff(x) that takes in a scalar as parameter and returns a scalar.
Say I have a vector X and I want to apply calculateStuff on every component in X, and get a vector of the results in return and store it in a new vector Y.
Clearly Y=calculateStuff(X) is illegal, is there a way I can do this besides looping?
You have three options:
modify calculateStuff so that it can take arrays and return arrays
write a loop
use arrayfun to hide the loop: Y = arrayfun(#calculateStuff,X)
Most Matlab operations will let you input a matrix and return a matrix. You should be able to re-write calculateStuff() to take a matrix and return a matrix. That is generally MUCH faster than using a for loop. Loops in Matlab are very expensive time-wise.
The sorts of things you need to look at are "dot" versions of normal operations. For example instead of
y = z * x;
do
y = z .* x;
The first will do a matrix multiplication, which is probably not what you want when vectorizing code. The second does an element-by-element multiplication of z and x.
See here and search for "The dot operations".