Borrar filtros
Borrar filtros

Value assignment to vector, without loop

19 visualizaciones (últimos 30 días)
ckara
ckara el 13 de Mayo de 2020
Comentada: Tommy el 14 de Mayo de 2020
Any possible ways (-fastest preferably) of doing the following without a for loop:
out = zeros(20,1)
value = [1 2 3 4]
frm = [4 9 14 16]
to = [4 12 14 17]
for i=1:length(frm)
out(frm(i):to(i)) = value(i)
end

Respuesta aceptada

Tommy
Tommy el 13 de Mayo de 2020
Here's an option:
N = 20;
idx = (1:N)';
out = (idx >= frm & idx <= to)*value';
The indices in frm and to can't overlap, and out will have 0s wherever the values in value aren't placed.
Here's a similar method which doesn't use matrix multiplication:
N = 20;
out = zeros(N,1);
idx = (1:N)';
tf = idx >= frm & idx <= to;
out(any(tf,2)) = repelem(value, sum(tf));
No idea how these compare to other methods - including a for loop.
  2 comentarios
ckara
ckara el 13 de Mayo de 2020
Such an elegant solution. Thanks!
Your solution is way better than using arrayfun(), but out of pure curiosity, is there any solution using arrayfun, like: arrayfun(@(x) out(from:to)=value, x) ?
Tommy
Tommy el 14 de Mayo de 2020
Happy to help!
The way you've written it, I don't believe so, no. When you use arrayfun, assignment to your variable happens outside the call to arrayfun, e.g.
out = arrayfun(@(i) value(i), 1:numel(value))
% ^ equal sign is here
arrayfun can't selectively place values, then. It could work if the function you supply to arrayfun returns every value in out, including the 0s. Then you've got to create a function that will return an element of value where appropriate and a 0 elsewhere, which would require checking if the input index falls within any elements in frm and to.
Or, your arrayfun function could return just the non-zero values as well as the indices required to fill out, and then you could fill out in the next line of code. Or there's this monstrosity that I came up with, which returns []s in place of 0s (requiring the use of a cell array), then replaces the []s with 0s, and then converts to a matrix:
N = 20;
out = arrayfun(@(i) value(i>=frm&i<=to), 1:N, 'uni', 0);
out(cellfun(@isempty, out)) = {0};
out = cell2mat(out)';
There are loads of ways you could do it, but I doubt any of them beat the for loop you wrote above. Of course I may be overlooking something!

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by