subtracting elements in a vector
37 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Nikolas Spiliopoulos
el 25 de Feb. de 2017
Editada: John D'Errico
el 25 de Feb. de 2017
hi all,
an easy question for you:
I have a vector A= [0 1 4 10 18] how can I subtract the second element from the first, the third from the second ans so on? The final vector I would be to be=[1 3 7 11]
thanks!
0 comentarios
Respuesta aceptada
Más respuestas (1)
John D'Errico
el 25 de Feb. de 2017
Editada: John D'Errico
el 25 de Feb. de 2017
A for loop is always a viable solution to a problem when you see no easier way out. And a single for loop is not terribly inefficient. It is when you have doubly, triply nested loops that you usually want to look for a better, vectorized solution. So, first, how might I do this using a simple loop?
A= [0 1 4 10 18];
% initialize the result to the correct size,
% as well as compute the difference of the first pair
D = diff(A);
for k = 3:numel(A)
D(k-1) = A(k) - D(k-2);
end
D
D =
1 3 7 11
So the simple loop works. It is often the case where a loop is a good solution. In fact, looking for a less obvious, vectorized solution is not always worth the time to work it out. Only worry about vectorizing code where you know it will be valuable. Computer time is far cheaper than programmer time. As you improve in skill, you learn what operations are best done in a vectorized manner. You will then usually recognize those cases immediately, knowing when to loop, when to use vectorized code.
So lets first expand the problem. A little pencil and paper algebra should yield this as the result, enough for us to see the pattern:
[A2 - A1, A1 - A2 + A3, A2 - A1 - A3 + A4, A1 - A2 + A3 - A4 + A5]
We can now write some basic, vectorized code that will suffice, for a 5 element vector. I'll write some things out so that you can see the pattern.
syms A1 A2 A3 A4 A5
A = [A1,A2,A3,A4,A5];
D = cumsum(A.*[1 -1 1 -1 1])
D =
[ A1, A1 - A2, A1 - A2 + A3, A1 - A2 + A3 - A4, A1 - A2 + A3 - A4 + A5]
So if I look at the vector D, it looks very close to what I wrote above. With one more change, we have it:
D = D(2:end).*[-1 1 -1 1]
D =
[ A2 - A1, A1 - A2 + A3, A2 - A1 - A3 + A4, A1 - A2 + A3 - A4 + A5]
So, now can we write this in a form that will work on any vector, and do so without an explicit loop?
A = [0 1 4 10 18];
n = numel(A);
D = cumsum(A.*(mod(1:n,2)*2-1));
D = D(2:end).*(1-mod(1:n-1,2)*2);
Did it work? Of course it worked. Does it hurt my brain to look at it? Yes, because it is not at all obvious what it does.
D
D =
1 3 7 11
Was it worth the time spent to do this? Probably not, unless it is something you will do tremendously often. Otherwise, this is a case of optimization for no good purpose, because if you actually wanted to understand what those lines that I wrote did, it would take some effort to work it out, just as I did above.
Were I to use the vectorized code in my own work, I would add extensive comments that explain the exact purpose of the vectorized code, and how it works. That way, when I revisit the code a year later, I will have a chance of understanding it.
Finally, with some thought, we could probably write code for this that will work using the function filter. Since we already have a simple solution that is vectorized, why bother? Remember that programming elegance is not always worth the investment of programmer time.
Edit: The filter solution is:
D = filter(1,[1 1],A);
D(1) = [];
D
D =
1 3 7 11
2 comentarios
John D'Errico
el 25 de Feb. de 2017
TY Stephen.
As I thought, there is a simple solution that employs filter.
D = filter(1,[1 1],A);
D(1) = [];
D
D =
1 3 7 11
This solution may be obvious to some. Others will need to puzzle over the filter documentation. I admit that I had to read the help to determine the correct filter coefficients, even though I knew that filter could solve the problem. So, IF you do choose to use a solution like this, you may be advised to add comments explaining what it does.
Again, a simple loop is not always a bad thing.
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!